/* ═══════════════ КАРТОЧКА ЗАДАЧИ ═══════════════
   Зона: выдвижная панель .drawer и её формы (.db, .field, .kv, .statusbtns, .df),
   карточка v2 и v3 (.tc-…, .tc3-…), степпер стадий (.cyc-…), шаги (.sub-…),
   комментарии (.tc-comment…), история, доказательства сдачи (.proofmark,
   .proofbox, .pb-…, .pf), листы сдачи (.sd-…) и возврата (.retnote),
   напоминания, голос в карточке (.tcv-…), мини-таймлайн задачи,
   встроенная в страницу карточка (.task-inline).
   ПРАВИЛО РАЗРЕЗА: этот файл правит ОДИН агент за раз и только свою зону.
   Подключается ТРЕТЬИМ — после board, до moyo. */

/* причина возврата в карточке — ПЕРЕД лентой комментариев, а не внутри неё:
   искать её среди 15 сообщений исполнитель не будет */
.retnote{margin:14px 0 0;background:var(--st-review-bg);border-radius:12px;border-left:3px solid var(--st-review);
  padding:11px 13px;display:flex;flex-direction:column;gap:4px}
.retnote .rh{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--st-review)}
.retnote .rt{font-size:13.5px;line-height:1.45;color:var(--ink);white-space:pre-wrap}
.retnote .rw{font-size:11px;font-weight:500;color:var(--ink-2)}

/* ═════════════ DRAWER ═════════════ */
.scrim{position:fixed;inset:0;z-index:var(--z-scrim);background:rgba(30,26,20,.42);opacity:0;pointer-events:none;transition:opacity .2s}
.scrim.open{opacity:1;pointer-events:auto}
.drawer{position:fixed;z-index:var(--z-drawer);background:var(--surface);box-shadow:var(--sh-3);display:flex;flex-direction:column;
  transition:transform .24s var(--ease),width .22s var(--ease),border-radius .22s var(--ease)}
/* desktop: справа, без изменений; + необязательное «раскрыть на весь экран» (App.toggleDrawerExpand) */
.drawer{top:0;right:0;height:100%;width:min(460px,94vw);border-radius:var(--r-drawer) 0 0 var(--r-drawer);transform:translateX(100%)}
.drawer.open{transform:none}
.drawer.expanded{width:100%;border-radius:0}
/* закреплённая карточка задачи — выезжает СНИЗУ аккуратной панелью, вписанной
   в рабочую область (не на весь экран): по бокам поля, снизу не перекрывает
   .botnav, слева на широком десктопе не залезает под .side. */
@media(min-width:641px){
  .drawer.docked{top:auto;left:16px;right:16px;
    bottom:calc(var(--nav-h) + env(safe-area-inset-bottom) + 14px);
    width:auto !important;max-width:none !important;height:min(70vh,720px);
    border-radius:20px;border-left:1px solid var(--line);border-top:1px solid var(--line);
    box-shadow:0 -10px 40px rgba(30,26,20,.16);transform:translateY(calc(100% + 24px)) !important}
  .drawer.docked.open{transform:none !important}
  .drawer.docked.expanded{height:min(88vh,calc(100dvh - var(--nav-h) - 28px));border-radius:20px}
}
/* ТЗ 5.1: панель больше не стоит в потоке — рабочее поле занимает всю ширину,
   поэтому карточка выравнивается по краям .wrap без запаса на --side-w */
@media(min-width:901px){
  .drawer.docked{
    left:calc(max(0px,(100vw - var(--shell-w))/2) + 20px);
    right:calc(max(0px,(100vw - var(--shell-w))/2) + 20px)}
}
/* «Удалить» отодвинут от основных кнопок, чтобы не нажать случайно */
.df .df-del{margin-left:auto}
.df .df-del svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2}
.dh{display:flex;align-items:center;gap:10px;padding:16px 18px;border-bottom:1px solid var(--line);flex:none}
.dh .back{display:none;width:36px;height:36px;border-radius:10px;background:var(--surface-2);flex:none;place-items:center}
.dh .back svg{width:19px;height:19px;stroke:var(--ink-2);fill:none;stroke-width:2.2;stroke-linecap:round}
.dh .dtag{font-size:11px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--accent)}
.dh .expand{display:none;width:36px;height:36px;border-radius:10px;background:var(--surface-2);margin-left:auto;place-items:center}
.dh .expand svg{width:17px;height:17px;stroke:var(--ink-2);fill:none;stroke-width:2.2;stroke-linecap:round}
.dh .x{margin-left:auto;width:36px;height:36px;border-radius:10px;background:var(--surface-2);display:grid;place-items:center}
.dh .expand + .x{margin-left:0}
.dh .x svg{width:18px;height:18px;stroke:var(--ink-2);fill:none;stroke-width:2.2;stroke-linecap:round}
/* — важен порядок: базовые правила выше, медиа-переопределения ниже, иначе
   позже объявленное .dh .back{display:none} без медиа-условия всегда победит — */
@media(min-width:641px){.dh .expand{display:grid}}
@media(max-width:640px){
  /* провал в задачу на телефоне — весь экран, а не выехавшее меню сбоку (добавление, десктоп не трогаем) */
  .drawer{top:0;bottom:0;right:0;left:0;width:100%;height:100%;
    border-radius:0;transform:translateY(100%)}
  .drawer.open{transform:none}
  .dh .back{display:grid}
}
.db{flex:1;overflow-y:auto;padding:18px}
.db h2{font-size:19px;font-weight:600;margin:0 0 4px;line-height:1.25}
.db .trans{font-size:14px;color:var(--ink-2);margin:0 0 16px}
.field{margin-bottom:14px}
.field label{display:block;font-size:11px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-2);margin-bottom:6px}
.field input,.field select,.field textarea{width:100%;background:var(--surface-2);border:1px solid var(--line);
  border-radius:10px;padding:11px 13px;outline:none;transition:border .15s,box-shadow .15s}
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.field textarea{resize:vertical;min-height:64px}
.frow{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.kv{display:flex;gap:10px;padding:10px 0;border-top:1px solid var(--line);font-size:14px}
.kv:first-of-type{border-top:none}
.kv .k{width:120px;flex:none;color:var(--ink-2);font-weight:500;font-size:13px}
/* ⚠️ min-width:0 — НЕ КОСМЕТИКА, НА НЁМ ЕХАЛА КАРТОЧКА ВБОК. У флекс-элемента
   по умолчанию min-width:auto, то есть «не уже своего содержимого». Внутри .v
   стоят выпадашки «После» и «Подрядчик» (select.tc3-asg): собственная ширина
   select в Chrome — по самому длинному пункту списка, а пунктов там сотни имён.
   Замер 02.09, 375 px, порт группы СВОЙСТВА 304 px: select 553 px, .kv
   scrollWidth 657 при clientWidth 295 — горизонтальная прокрутка ВНУТРИ
   карточки на семи карточках стенда из девяти (258, 258, 208, 135, 134, 58, 15
   px). Лечится не обрезкой: .v получает право сжиматься, select — ширину по
   месту, и содержимое перестаёт вылезать. Стало 0 на всех девяти. */
.kv .v{flex:1;min-width:0;font-weight:500}
/* select внутри .v: ширину берёт от места, а не от длины самого длинного имени
   (правило .kv .ie-input выше ставит width:auto — оно про поля, лежащие прямо
   в .kv, и до вложенных в .v дотягиваться не должно) */
.kv .v>.ie-input{width:100%;max-width:100%}
/* ═══ СЛОЖНОСТЬ РАБОТЫ: ЛЕСТНИЦА ИЗ ПЯТИ СТУПЕНЕЙ СЛОВАМИ ═══════════════════
   Было: пять кнопок-ЦИФР в ряд. Цифра без слова не говорит ничего — поле стояло
   у 0 живых карточек из 80. Стало: ступень занимает СТРОКУ (цифра · слово ·
   правило), ряд превращается в столбец, и правило читается там же, где выбор.
   Тач-цель строки 44 (WCAG 2.2 SC 2.5.8) — высотой, а не только шириной:
   строка тянется во всю ширину .v, и промахнуться по ней нельзя.
   Один акцент («Тихая доска»): выбранная — акцентом, подсказанная — ПУНКТИРОМ
   того же акцента, второго яркого цвета не заводим. */
.slz{display:flex;flex-direction:column;gap:6px}
.slz-b{display:flex;align-items:center;gap:10px;width:100%;min-height:44px;
  padding:6px 10px;border:0;border-radius:var(--r2);background:var(--surface);
  color:var(--ink-2);font:inherit;font-size:13px;font-weight:600;cursor:pointer;
  text-align:left;box-shadow:var(--sh-1);transition:background .15s,color .15s}
.slz-b .slz-n{flex:none;min-width:22px;text-align:center;font-size:14px}
/* текст ступени сжимается, а не выпихивает строку в горизонтальную прокрутку —
   та же беда, что лечило правило .kv .v выше */
.slz-b .slz-tx{display:flex;flex-direction:column;min-width:0;line-height:1.25}
.slz-b .slz-w{font-weight:600}
.slz-b .slz-p{font-weight:400;font-size:11.5px;color:var(--ink-3);opacity:.85}
.slz-b.on{background:var(--accent);color:var(--on-accent)}
.slz-b.on .slz-p{color:var(--on-accent);opacity:.8}
/* ПОДСКАЗКА — СЕРЫМ И ПУНКТИРОМ, пока человек её не подтвердил: платформа
   предлагает, решает человек (ISO 9241-110, контролируемость) */
.slz-b.sovet{box-shadow:inset 0 0 0 1.5px var(--accent)}
.slz-hint{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin-top:8px;
  font-size:12px;font-weight:500;color:var(--ink-2)}
.slz-take{min-height:44px;padding:0 14px;border:0;border-radius:var(--r2);
  background:var(--surface-2);color:var(--ink);font:inherit;font-size:12.5px;
  font-weight:600;cursor:pointer;box-shadow:var(--sh-1)}
/* след смены после начала работы — числом, рядом с лестницей */
.slz-sled{margin-top:6px;font-size:11.5px;font-weight:500;color:var(--ink-2)}
/* ЛЕСТНИЦА ЗАНИМАЕТ СТРОКУ ЦЕЛИКОМ, А НЕ ПОЛОВИНУ. У обычной .kv подпись
   держит 120 px, и на 375 значению остаётся 174 — правило ступени ломалось там
   на три строки, ступень росла до 86 px, а в порт группы влезало две из пяти
   (замер 03.09, 375×667: порт 155, видно 2). Подпись уходит НАД лестницей,
   ширина значения становится полной (295), правило встаёт в одну-две строки. */
.slz-kv{flex-direction:column;align-items:stretch;gap:6px}
.slz-kv .k{width:auto}
.statusbtns{display:flex;gap:8px;margin-bottom:16px}
.statusbtns button{flex:1;height:40px;border-radius:10px;background:var(--surface-2);font-size:13px;font-weight:600;color:var(--ink-2);transition:.15s;box-shadow:var(--sh-1)}
.statusbtns button.on{color:var(--on-accent)}
.statusbtns button.on.s-new{background:var(--st-new)}
.statusbtns button.on.s-in_progress{background:var(--st-prog)}
.statusbtns button.on.s-on_review{background:var(--st-review)}
.statusbtns button.on.s-done{background:var(--st-done)}
.hist{margin-top:6px}
.hist .he{display:flex;gap:9px;padding:8px 0;font-size:12.5px;color:var(--ink-2);border-top:1px dashed var(--line)}
.hist .he:first-child{border-top:none}
.hist .he .hd{width:8px;height:8px;border-radius:50%;background:var(--accent);margin-top:5px;flex:none}
.df{display:flex;gap:9px;padding:14px 18px;border-top:1px solid var(--line);flex:none;flex-wrap:wrap}
.df .btn{height:44px;flex:none}
.srcchip{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:600;color:var(--ink-2);
  background:var(--surface-2);padding:4px 9px;border-radius:7px}
.srcchip svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2}

/* ═════════════ ВОССТАНОВЛЕННЫЙ ЧЕРНОВИК ЗАДАЧИ ═════════════ */
.draftbar{display:flex;align-items:center;gap:10px;margin:0 0 14px;padding:9px 12px;border-radius:12px;
  background:var(--accent-soft);border-left:3px solid var(--accent)}
.draftbar .db-ic{color:var(--accent);flex:none;display:grid;place-items:center}
.draftbar .db-ic svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.draftbar .db-tx{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1}
.draftbar .db-tx b{font-size:13px;font-weight:600;color:var(--ink)}
.draftbar .db-tx span{font-size:11.5px;font-weight:500;color:var(--ink-2)}
.draftbar .db-x{min-height:44px;padding:0 13px;border-radius:10px;font-size:12.5px;font-weight:600;
  color:var(--accent);background:var(--surface);flex:none;box-shadow:var(--sh-1)}

/* ═════════════ КАРТОЧКА ЗАДАЧИ v2 (перенесено из mockups/task_card_v2.html) ═════════════ */
.tc-when{font-size:11px;color:var(--ink-2);margin-left:auto}
.tc-trans{color:var(--ink-2);font-style:italic;font-size:13.5px;margin:2px 0 0}
.tc-notrans{color:var(--ink-2);font-size:12px;margin:4px 0 0;display:flex;align-items:center;gap:5px}
/* ─── АВТОПЕРЕВОД (аддитивно): свёрнутое поле ручного перевода в формах ─── */
.trans-fold{font-size:12px;color:var(--ink-2);display:flex;align-items:center;gap:8px;flex-wrap:wrap;min-height:22px;padding:2px 0}
.trans-fold .tf-val{font-style:italic;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.trans-fold .tf-link{color:var(--accent);cursor:pointer;font-size:11.5px;white-space:nowrap;text-decoration:underline;text-underline-offset:2px}
.trans-fold .tf-link:hover{opacity:.8}
.tc-hero{display:flex;align-items:center;gap:14px;margin:14px 0;padding:12px;border-radius:13px;background:var(--surface-2)}
.tc-hero .ring{width:56px;height:56px;flex:none}
.tc-hero .ring .pct{font-size:13px}
.tc-hero-info{flex:1;min-width:0}
.urgchip{display:inline-flex;align-items:center;gap:5px;font-size:13px;font-weight:700;padding:4px 10px;border-radius:999px;margin-bottom:5px}
.urgchip svg{width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:2;flex:none}
.urgchip.fire{background:var(--st-fire-bg);color:var(--st-fire)}
.urgchip.soon{background:var(--st-prog-bg);color:var(--st-prog)}
.urgchip.ok{background:var(--surface);color:var(--ink-2)}
.urgchip.done{background:var(--st-done-bg);color:var(--st-done)}
.tc-hero-sub{font-size:12px;color:var(--ink-2)}
.tc-hero-sub a{color:var(--accent);font-weight:600;cursor:pointer}
/* ═══ широкая докнутая панель (.drawer.docked): шапка компактной строкой,
   тело — 2 колонки вместо узкого столбца. Ниже 901px схлопывается в одну. ═══ */
.tc-head{margin-bottom:0}
/* ── ШАПКА: компактная строка-band в 2 зоны, без растяжки заголовка/кнопок ── */
.tc-band{display:flex;align-items:flex-start;gap:24px}
.tc-band-left{flex:1 1 auto;min-width:0;max-width:640px}
.tc-band-left .tc-meta{display:flex;align-items:center;gap:8px;margin-bottom:6px;min-height:18px}
.tc-band-left .tc-meta .tc-when{margin-left:0;font-size:11px;color:var(--ink-2)}
.tc-band-left h2{font-size:20px;font-weight:600;line-height:1.25;margin:0;max-width:620px}
.tc-band-left .tc-trans,.tc-band-left .tc-notrans{max-width:620px}
.tc-band-right{flex:none;display:flex;align-items:center;gap:14px;padding:10px 12px;border-radius:13px;
  background:var(--surface-2)}
.tc-band-right .ring{width:56px;height:56px;flex:none}
.tc-state-stack{display:flex;flex-direction:column;gap:9px;align-items:stretch}
.tc-state-stack .urgchip{margin-bottom:0;align-self:flex-start}
.tc-state-stack .statusbtns{margin:0;width:300px;gap:6px}
.tc-state-stack .statusbtns button{flex:1;min-width:90px}
.tc-head-divider{height:1px;background:var(--line);margin:16px 0}
/* ── ТЕЛО: 2 колонки, левая ограничена, правая доминирует и добивается по высоте ── */
.tc-grid{display:grid;grid-template-columns:minmax(360px,460px) minmax(0,1fr);gap:0 32px;align-items:stretch}
.tc-col{min-width:0}
.tc-col-left{display:flex;flex-direction:column}
.tc-col-left .mini-tl{margin-top:auto}
.tc-col-right{display:flex;flex-direction:column;min-width:0}
.kv-pair{display:grid;grid-template-columns:1fr 1fr;gap:0 16px}
.kv-pair .kv{border-top:1px solid var(--line)}
.kv-pair .kv .k{width:auto;min-width:0;margin-right:8px}
@media(min-width:901px){
  /* заполнение вертикали: .db — колонка, тело растёт, лента комментариев забирает высоту */
  .db{display:flex;flex-direction:column}
  .tc-head{flex:none}
  .tc-head-divider{flex:none}
  .tc-grid{flex:1;min-height:0;grid-template-rows:1fr}
  .tc-col-right{min-height:0;overflow-y:auto}
  .tc-col-right .tc-comments{flex:1;min-height:0;display:flex;flex-direction:column}
  .tc-col-right #tcCommentsList{flex:1;min-height:0;overflow-y:auto}
}
@media(max-width:900px){
  .tc-grid{grid-template-columns:1fr;gap:0}
  .tc-band{flex-wrap:wrap}
  .tc-band-left{max-width:none;flex:1 1 100%}
  .tc-band-right{flex:1 1 100%}
  .tc-state-stack{flex:1}
  .tc-state-stack .statusbtns{width:auto}
  .tc-col-left .mini-tl{margin-top:14px}
}
@media(max-width:640px){
  .tc-band-right{flex-wrap:wrap;justify-content:center}
  .tc-state-stack{flex:1 1 100%}
  .tc-state-stack .statusbtns button{min-width:0}
}

/* ═══════════════ КАРТОЧКА ЗАДАЧИ v3 — ЯДРО ЦИКЛА (спец. Б-1) ═══════════════
   Порядок: ЧТО → КОМУ/ОТ КОГО/К КОГДА → СТАДИЯ ЦИКЛА → ГЛАВНОЕ ДЕЙСТВИЕ →
   ЧТО НОВОГО → ГДЕ → ДЕТАЛИ → ВЛОЖЕНИЯ. Всё аддитивно: старые классы живы. */
.tc3-top{display:flex;gap:12px;align-items:flex-start}
/* ⚠️ min-height полосы статуса — НЕ декорация: именно она задаёт высоту всего
   блока названия. Замер: собственная высота содержимого 46 px, порог 52 торчал
   на 6 px впустую. 44 — тач-норма, ниже опускать нельзя, обнулять тем более:
   на коротком названии блок схлопнется. */
.tc3-bar{width:4px;border-radius:3px;flex:none;align-self:stretch;min-height:44px;background:var(--st-new)}
.tc3-bar.st-in_progress{background:var(--st-prog)}
.tc3-bar.st-on_review{background:var(--st-review)}
.tc3-bar.st-done{background:var(--st-done)}
/* точка срочности вместо кольца: 18 px, читается с одного взгляда, не ест шапку */
.tc3-urg{flex:none;align-self:flex-start;min-width:18px;height:18px;border-radius:9px;padding:0 5px;
  display:inline-grid;place-items:center;font-size:10.5px;font-weight:700;font-variant-numeric:tabular-nums;
  background:var(--surface-2);color:var(--ink-2);margin-top:3px}
/* ⚠️ ЗАЛИВКА — ОБЪЯВЛЕННАЯ ПАРА --alarm-bg, А НЕ САМОДЕЛЬНЫЙ ЗАМЕС. Стояло
   color-mix(--st-fire 15%): на светлой теме подложка выходила #E6DBD4, и
   #94543E на ней давал 4.3 при норме AA 4.5 — сторож вёрстки печатал ровно
   один брак контраста на карточке, и печатал его на всех четырёх ширинах
   (замер 03.09, карточки 620 и 787, чип «+6»). С парой --alarm/--alarm-bg
   выходит 4.87 на светлой и 5.88 на тёмной (числа судьи 03.09; мои 4.91 и 5.90
   были посчитаны в столбик и на сотые разошлись). §1 стиля: цвета из таблицы,
   а замес процентом — это новый цвет, которого в таблице нет. */
.tc3-urg.fire{background:var(--alarm-bg);color:var(--alarm)}
.tc3-urg.soon{background:var(--accent-soft);color:var(--accent)}
.tc3-what{flex:1;min-width:0}
/* ОДНА СТРОКА, НЕ ДВЕ (жалоба владельца 31.08): вторая строка с переводом
   снята совсем, а само имя больше не занимает два этажа — длинное обрезается
   многоточием и раскрывается тапом (tcMarkTitleClamp → App.toggleTitleFull).
   ⚠️ СТРОКА ОДНА, А КОРОБКА ВСЁ РАВНО 44. Клик висит на самом h2, и одна
   строка 19/1.3 дала бы цель в 24.7 px — прямое нарушение §3 (тач-цель ≥44).
   Раньше норму держали два этажа текста (49 px); теперь её держат отступы,
   посчитанные от кегля: (44 − 1.3em)/2 сверху и снизу. Кегль тут меняется
   (на телефоне 17 px), поэтому число НЕ вбито — при 19 px выходит 9.65,
   при 17 px 10.95, коробка в обоих случаях ровно 44, а строка стоит по
   центру — вровень с полосой статуса и крестиком, у которых те же 44.
   ⚠️ ОБРЕЗКА ПО ШИРИНЕ, А НЕ line-clamp:1. Это не вкусовщина: сторож вёрстки
   прощает многоточие только по ГОРИЗОНТАЛИ (§10, checkClipped: «soft && !badY»),
   а вертикальный срез считает обрезкой и ставит «БРАК — владельцу не
   показывать». Замер на живой карточке: с `-webkit-line-clamp:1` длинное имя
   давало `h2#tcTitle_658 · высота +25px` — обрезка 1 на 1440. Тем же приёмом
   (nowrap + text-overflow) режется вся остальная длинная строка карточки —
   крошка «Где», значения ячеек: одиннадцать таких на экране сторож пропускает
   молча. Заодно nowrap держит одну строку жёстче клампа: перенос невозможен. */
.tc3-what h2{font-size:19px;font-weight:600;line-height:1.3;margin:0;overflow-wrap:anywhere;
  min-height:44px;padding:calc((44px - 1.3em)/2) 0;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Раскрытое длинное название. Класс вешает tcAfterMount и только если текст
   реально не поместился, — иначе на коротком названии в карточке появлялась бы
   интерактивная цель высотой 22 px (тач-норма 44).
   Раскрытому переносы возвращаются (иначе одна бесконечная строка), а вместе с
   ними и рост коробки — на то и раскрытие. */
.tc3-what h2.full{white-space:normal;overflow:visible;text-overflow:clip}
.tc3-what h2.clampable{cursor:pointer}
.tc3-ring{flex:none}
/* Крестик переехал из строки «Задача» в блок названия: строка убрана целиком,
   а другой кнопки закрытия у карточки нет — своего адреса (hash/pushState) у
   неё тоже нет. Свой селектор, а не .dh .x: тот же крестик стоит в девяти
   модалках, там 36 px и раздувать его нельзя. */
.tc3-x{flex:none;width:44px;height:44px;border-radius:12px;background:var(--surface-2);
  display:grid;place-items:center;color:var(--ink-2);margin:-3px -6px 0 0}
.tc3-x svg{width:19px;height:19px;stroke:currentColor;fill:none;stroke-width:2.2;stroke-linecap:round}
.tc3-x:hover{background:var(--line)}
/* ── строка чипов: поставил · исполнитель · срок ── */
/* ⚠️ Чипы «кому · от кого · к когда» были flex-wrap: ширина каждого зависела от
   длины текста, и задача БЕЗ исполнителя («не назначен» длиннее любого имени)
   ломала раскладку — блок вырастал со 109 до 175 px, а до сути карточки на
   телефоне становилось 319 px. Замер владельца: «разъезжается картинка, сверху
   съедается место». Сетка убирает зависимость от длины: места ровно столько,
   сколько отвели, а длинное значение обрезается многоточием. */
/* Чипов два, а не три: «Поставил» ушёл (автор и так подписан первой стадией
   цикла ниже). Две колонки и на телефоне, и на десктопе — третья была нужна
   третьему чипу, которого больше нет. */
.tc3-chip>span:last-child{min-width:0;flex:1}
/* min-height, а НЕ height: ряд и так встаёт ровно в 44 (поле даты 44 + нулевые
   отступы чипа), а жёсткая высота обрезала бы чип исполнителя, если у человека
   есть ник — там третья строка. Пусть лучше вырастет, чем обрежет. */
.tc3-chip{display:flex;align-items:center;gap:7px;background:var(--surface-2);border-radius:11px;
  padding:0 10px 0 6px;font-size:12.5px;min-height:44px;min-width:0}
.tc3-chip .lbl{color:var(--ink-2);font-size:10px;text-transform:uppercase;letter-spacing:.05em;display:block;line-height:1.3}
.tc3-chip .val{font-weight:600;font-size:13px;display:block;line-height:1.3;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;max-width:100%}
.tc3-chip .val.soft{font-weight:500;color:var(--ink-2)}
/* min-height 44, а не 26: сторож §10 поймал выпадашку исполнителя на 26 px —
   ниже тач-нормы §3. Ряд чипов с выпадашками вырастает до ~57 px (подпись 13 +
   поле 44); плоские чипы соседям не мешают — сетка тянет их на ту же высоту,
   содержимое центруется. Волна 5 добавила вторую такую же выпадашку («Следит»),
   чинить пришлось обе разом. */
.tc3-chip .tc3-asg{width:100%;min-width:0;max-width:100%;height:auto;min-height:44px;
  padding:2px 4px;font-size:13.5px;font-weight:600;background:transparent;border:none;
  color:var(--ink);cursor:pointer;border-radius:6px}
.tc3-chip .tc3-asg:hover{background:var(--accent-soft)}
.tc3-chip .tc3-asg:focus{outline:2px solid var(--accent);outline-offset:1px}
.tc3-chip .nick{font-size:10.5px;color:var(--ink-2);font-weight:500}
/* ⚠️ Подпись «СРОК» — В СТРОКУ слева, а не этажом над полем. Пока она стояла
   этажом, ряд чипов давал 55 px, а растянутое до тач-нормы поле даты — 57.
   Только строкой ряд укладывается ровно в 44. */
.tc3-chip.due{padding:0 0 0 9px;gap:0}
.tc3-chip.due>span:last-child{display:flex;align-items:center;gap:6px;align-self:stretch}
/* Подпись чипа срока мельче соседней и без разрядки — не украшательство:
   собственная ширина поля даты в Chrome 124 px, и каждый лишний пиксель подписи
   отъедается у неё. Худшее слово — «ПРОСРОЧЕНО»; на 9 px оно оставляет полю
   ровно столько, чтобы дата читалась целиком. */
.tc3-chip.due .lbl{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:9px;letter-spacing:.02em}
/* поле даты занимает чип на всю высоту: 32 px не проходили тач-норму, а лишние
   отступы вокруг вернули бы ряду те самые 13 px, ради которых всё затевалось */
/* flex-basis 70 px и запрет сжиматься: столько занимает сама дата «11.08.2026»
   с отступами. На 360 px у просроченной задачи подпись «ПРОСРОЧЕНО» отжимала
   поле до 62 px, и дата обрезалась — теперь сжимается подпись, а не дата. */
.tc3-chip.due input[type=date]{flex:1 0 70px;min-width:70px;width:100%;box-sizing:border-box;height:44px;
  border:1px solid var(--line);background:var(--surface);border-radius:0 11px 11px 0;
  padding:0 5px;font:inherit;font-size:12.5px;font-weight:600;color:var(--ink);cursor:pointer}
/* Родная иконка календаря убрана намеренно, а не «потерялась»: своя ширина поля
   в Chrome — 122 px, а на просроченной задаче подпись «ПРОСРОЧЕНО» оставляет
   полю 77 px, и иконка обрезалась бы наполовину. Вместо неё календарь
   открывает нажатие по всему полю (showPicker), то есть цель 44 px, а не 24. */
.tc3-chip.due input[type=date]::-webkit-calendar-picker-indicator{display:none}
.tc3-chip.due.od{background:var(--alarm-bg)}
.tc3-chip.due.od .lbl,.tc3-chip.due.od .val{color:var(--alarm);font-weight:700}
.tc3-chip.due.td .lbl{color:var(--accent);font-weight:700}
/* .todaymark больше не рисуется в чипе срока (слово ушло в место подписи),
   правило оставлено: класс может понадобиться другому носителю срока */
.tc3-chip.due .todaymark{margin-left:6px;background:var(--alarm);color:var(--on-accent);border-radius:999px;
  font-size:10px;font-weight:700;padding:2px 8px;white-space:nowrap}
/* ТЗ 4.2б «Заполните позже»: пустые срок/ответственный при выходе из карточки.
   Терракота-обводка — канал СРОКА по регламенту, статусную заливку не трогаем;
   появляется плавно и один раз, ничего не мигает. */
.tc3-chip.miss{box-shadow:inset 0 0 0 2px var(--alarm-line);transition:box-shadow .3s ease-out}
.tc3-filllater{display:flex;align-items:center;gap:8px;margin:8px 0 0;font-size:13px;font-weight:500;color:var(--ink)}
.tc3-filllater[hidden]{display:none}
.tc3-filllater svg{width:16px;height:16px;flex:none;color:var(--alarm-line);stroke:currentColor;fill:none;
  stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
/* ТЗ 4.2а мини-форма «+ Задача»: строка адреса и строчная ссылка на полную форму */
.qt-ctx{display:flex;align-items:center;gap:8px;margin:0 0 14px;padding:10px 12px;border-radius:10px;
  background:var(--surface);font-size:13px;font-weight:500;color:var(--ink-2)}
.qt-ctx svg{width:16px;height:16px;flex:none;stroke:currentColor;fill:none;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}
.qt-all{display:inline-flex;align-items:center;min-height:44px;padding:0 4px;background:none;border:0;
  color:var(--accent);font-size:14px;font-weight:600;cursor:pointer}
.qt-all:hover{color:var(--accent-hover)}
/* ── ЧИП «СКРЫТАЯ» В ФОРМЕ ЗАВЕДЕНИЯ ──
   Тач-цель 44 px, как у чипов приоритета рядом: форму заполняют пальцем с
   телефона. В покое чип обычный, нажатый — сплошной, чтобы «скрытая» читалось
   с одного взгляда и человек не создал личную карточку по недосмотру. */
.qt-hide-row{display:flex;margin:8px 0 2px}
.qt-hide{display:inline-flex;align-items:center;gap:8px;min-height:44px;padding:0 14px;
  border:1px solid var(--line);border-radius:10px;background:var(--card);
  color:var(--ink-2);font-size:14px;font-weight:600;cursor:pointer}
.qt-hide:hover{border-color:var(--accent)}
/* нажатый чип: буквы цветом фона страницы, а не белым. Белое по светло-синему
   акценту тёмной темы даёт 2,2:1 — сторож вёрстки такой контраст бракует. */
.qt-hide.on{background:var(--accent);border-color:var(--accent);color:var(--bg)}
.qt-hide svg{width:16px;height:16px;flex:none;stroke:currentColor;fill:none;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}
/* ── ПОМЕТКА «СКРЫТАЯ» В ШАПКЕ КАРТОЧКИ ──
   Стоит НАД названием и занимает свою строку: владелец должен видеть признак
   раньше, чем прочтёт заголовок. Не кнопка — трогать нечего, поэтому обычный
   текст без тач-нормы; снимается признак там же, где ставился, — в меню «⋯». */
.tc3-hid{display:inline-flex;align-items:center;gap:6px;margin:0 0 6px;padding:3px 9px;
  border-radius:999px;background:var(--surface-2);border:1px solid var(--line);
  font-size:12px;font-weight:600;letter-spacing:.01em;color:var(--ink-2)}
.tc3-hid svg{width:14px;height:14px;flex:none;stroke:currentColor;fill:none;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}
/* ── степпер цикла из 4 шагов ── */
.cyc{display:flex;gap:0;margin:16px 0 0;background:var(--surface-2);border-radius:13px;padding:12px 10px;overflow-x:auto}
/* Шаги полосы — НАСТОЯЩИЕ кнопки (дефект №20): пальцем перетащить карточку нельзя
   (drag&drop живёт на HTML5 DnD), и полоса была единственным местом, где статус
   виден, но не меняется. Запрещённый шаг не прячем и не гасим намертво: он
   приглушён, но нажимается и говорит, ПОЧЕМУ нельзя. */
.cyc-s{flex:1 1 0;min-width:104px;display:flex;flex-direction:column;gap:4px;position:relative;
  padding:5px 6px;min-height:44px;text-align:left;justify-content:flex-start;border-radius:9px;
  transition:background .18s var(--ease),opacity .18s var(--ease)}
.cyc-s:hover{background:var(--surface)}
.cyc-s:active{transform:scale(.98)}
.cyc-s.here{cursor:default}
.cyc-s.here:hover{background:none}
.cyc-s.off{opacity:.5}
.cyc-s:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.cyc-s .rail{height:4px;border-radius:3px;background:var(--line)}
.cyc-s.past .rail{background:var(--st-done)}
.cyc-s.cur .rail{background:var(--cyc-c,var(--accent))}
.cyc-s .nm{font-size:11.5px;font-weight:700;color:var(--ink-2);letter-spacing:.01em}
.cyc-s.cur .nm{color:var(--cyc-c,var(--accent))}
.cyc-s.past .nm{color:var(--ink)}
.cyc-s .fact{font-size:10.5px;color:var(--ink-2);line-height:1.35;overflow-wrap:anywhere}
.cyc-note{font-size:11.5px;color:var(--ink-2);margin:8px 0 0;display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.cyc-ret{background:var(--st-review-bg);color:var(--st-review);border-radius:999px;padding:2px 9px;font-size:10.5px;font-weight:700}
/* ── главное действие ── */
.tc3-act{margin:16px 0 0;display:flex;flex-direction:column;gap:10px}
.tc3-act-row{display:flex;gap:10px;flex-wrap:wrap;align-items:center}
.tc3-main{min-height:52px;padding:0 26px;font-size:15px;font-weight:700;border-radius:12px;
  background:var(--accent);color:var(--on-accent);box-shadow:var(--sh-1);display:inline-flex;align-items:center;gap:9px;
  transition:background .15s,transform .12s}
/* ⚠️ иконки в кнопках цикла ОБЯЗАНЫ иметь размер — без него кнопка раздувается
   в пол-экрана (клякса, пятый заход того же бага) */
.tc3-main svg,.tc3-second svg{width:17px;height:17px;flex:none;stroke:currentColor;fill:none;
  stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.tc3-main:hover{background:var(--accent-hover)}
.tc3-main:active{transform:translateY(1px)}
.tc3-main.rev{background:var(--st-review)}
.tc3-main.ok{background:var(--st-done)}
.tc3-second{min-height:44px;padding:0 16px;border-radius:11px;background:var(--surface-2);color:var(--ink);
  font-size:13.5px;font-weight:600}
.tc3-second:hover{background:var(--accent-soft);color:var(--accent)}
.tc3-plate{display:flex;align-items:center;gap:10px;background:var(--surface-2);border-radius:12px;
  padding:13px 15px;font-size:13.5px;font-weight:600;line-height:1.4;min-height:52px}
.tc3-plate svg{width:20px;height:20px;flex:none;stroke:currentColor;fill:none;
  stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
.tc3-plate.review{background:var(--st-review-bg);color:var(--st-review)}
.tc3-plate.done{background:var(--st-done-bg);color:var(--st-done)}
.tc3-plate .sub{display:block;font-weight:500;font-size:12px;color:var(--ink-2);margin-top:2px}
.tc3-sheet{background:var(--surface-2);border-radius:12px;padding:12px;display:flex;flex-direction:column;gap:8px}
.tc3-sheet textarea,.tc3-sheet input{width:100%;border:1px solid var(--line);background:var(--surface);
  border-radius:9px;padding:9px 11px;font:inherit;font-size:13px;color:var(--ink);resize:vertical}
.tc3-sheet textarea{min-height:64px}
.tc3-sheet .sh-l{font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--ink-2)}
.tc3-sheet .sh-row{display:flex;gap:9px;flex-wrap:wrap;align-items:center}
/* ── лента «что нового» ── */
.tc3-feed{display:flex;flex-direction:column;gap:8px;margin-top:4px}
.tc3-fe{display:flex;gap:9px;font-size:12.5px;line-height:1.45}
.tc3-fe .fi{width:22px;height:22px;border-radius:50%;background:var(--surface-2);display:grid;place-items:center;flex:none;color:var(--ink-2)}
.tc3-fe .fb{min-width:0;flex:1}
.tc3-fe .fw{font-size:10.5px;color:var(--ink-2);margin-top:1px}
.tc3-newline{display:flex;align-items:center;gap:9px;font-size:10.5px;font-weight:700;letter-spacing:.04em;
  text-transform:uppercase;color:var(--accent);margin:4px 0}
.tc3-newline:before,.tc3-newline:after{content:"";flex:1;height:1px;background:var(--accent-soft)}
/* ── свёрнутые разделы ── */
/* Подзадачи-квадратики. Владелец: «разбиваю на подзадачи, чтобы мозг не
   саботировал; закрашивание квадратиков — приятный ритуал». Держим лёгким:
   строка, галочка, ничего лишнего. */
/* container-type — НЕ украшение: строка шага перестраивается по ширине САМОГО
   блока шагов, а не карточки. Шаги живут в двух местах разной ширины: колонка
   набора 320 px на широком экране и полная ширина карточки под лентой на узком.
   Замер 02.09 (карточка 620, 8 шагов): при колонке 320 кнопки «Сдать сделанное»
   115 + «Блок» 47 + крестик 44 = 206 px не сжимаются никогда (flex:none), тексту
   шага оставалось 37 px, и блок вырастал до 983 px при видимых 434 — 549 px
   слепой прокрутки. Ширина карточки этого не видит: она одинакова и когда шаги
   в колонке 320, и когда во всю ширину. */
.subs{border-top:1px solid var(--line);margin-top:14px;padding-top:12px;
  container-type:inline-size;container-name:shagi}
/* ── УЗКИЙ БЛОК ШАГОВ: КНОПКИ ВТОРЫМ ЭТАЖОМ ПОД ТЕКСТОМ ──
   Порог 420 посчитан от неснимаемого: 206 px кнопок + крестик уже внутри, плюс
   галочка 24 и просветы 33 = 263; чтобы тексту шага осталась хотя бы половина
   строки (по образцу Fieldwire, где текст шага — главное), блок должен быть
   шире 420. Уже — этаж второй: первая строка «галочка · текст · крестик»,
   вторая «Сдать сделанное · Блок» с отступом под текст.
   Цена названа числом: несделанный шаг стоит 88 px вместо 44, сделанный —
   по-прежнему 44 (у него этих кнопок нет вовсе).
   ⚠️ row-gap:0 ЗДЕСЬ РАБОТАЕТ ТОЛЬКО ПОТОМУ, ЧТО БАЗОВОЕ ПРАВИЛО НИЖЕ ПИШЕТ
   column-gap, А НЕ gap. Ловушка стоила замера 02.09: базовый `.sub-row{gap:11px}`
   (строка ~500) идёт ПОЗЖЕ этого блока при той же силе селектора и переписывал
   обе оси разом — computed row-gap выходил 11 px вместо нуля. Одиннадцать
   пикселей на каждом двухэтажном шаге: список шагов на карточке 620 весил
   694 px при видимых 195, слепой прокрутки 499 при потолке признака №25 в 434.
   Меняешь gap у .sub-row — меняй column-gap, иначе брак вернётся молча. */
/* ═══ ПОРОГ ОПУЩЕН 420 → 279.98 (02.09) ══════════════════════════════════════
   Он ВЫВОДИТСЯ из неснимаемого, и неснимаемое стало другим. Было 263 px
   («Сдать сделанное» 111 + «Блок» 44 + крестик 44 + просветы 33 + галка 24)
   при блоке шагов 299 — то есть порог 420 срабатывал ВСЕГДА, и второй этаж
   стоял постоянно. Слова ушли: в строке два значка вместо трёх текстовых
   органов, неснимаемое 144 (набивка 4+4, галка 24, зазоры 11+11, цели 44+44,
   зазор 2). Чтобы тексту осталась половина строки — 288; берём 280.
   ⚠️ ЧИСЛО 279.98, А НЕ 280. Ровно на 280 запрос сработал бы, и признак
   «строка ≤48 при ширине блока ≥280» краснел бы на границе сам от себя.
   Порог не удалён, а опущен: на экране 320 (блок 241) второй этаж честно
   возвращается — это предохранитель, названный числом, а не рабочий режим.
   ⚠️ row-gap:0 РАБОТАЕТ ТОЛЬКО ПОТОМУ, ЧТО БАЗОВОЕ ПРАВИЛО НИЖЕ ПИШЕТ
   column-gap, А НЕ gap — см. предупреждение выше, оно в силе. */
@container shagi (max-width:279.98px){
  .sub-row{flex-wrap:wrap;row-gap:0;padding-bottom:4px}
  .sub-row>.sub-tx{flex:1 1 0;min-width:60px}
  .sub-row>.sub-ic{order:5}
}
.subs-h{display:flex;align-items:center;gap:8px;font-size:11px;font-weight:700;
  letter-spacing:.06em;text-transform:uppercase;color:var(--ink-2);margin-bottom:9px}
.subs-h .cnt{margin-left:auto;font-weight:700;color:var(--ink-2);font-variant-numeric:tabular-nums}
/* ⚠️ страховка от «кляксы»: svg без width/height браузер рисует в натуральную
   величину. Ловили седьмой раз — теперь размер задан и в иконках, и здесь. */
.subs-h svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2.4;
  stroke-linecap:round;stroke-linejoin:round;flex:none}
/* ссылка внутри пользовательского текста: заметная, но не кричащая */
.lnk{color:var(--accent);text-decoration:underline;text-underline-offset:2px;
  text-decoration-thickness:1px;word-break:break-word}
.lnk:hover{text-decoration-thickness:2px}
.subs-bar{height:5px;border-radius:3px;background:var(--surface-2);overflow:hidden;margin-bottom:11px}
.subs-bar i{display:block;height:100%;background:var(--st-done);transition:width .35s var(--ease)}
/* ═══ ЭТАПНАЯ СДАЧА (P3). Полоска подтверждённого прогресса — второй ряд под
   обычной: ДЛИНА = сколько ПРИНЯТО (по ves обязательных). Цвета — только
   переменные статусов, третий канал не изобретаем. */
.et-podtv{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:11px;
  font-weight:700;color:var(--ink-2);margin:-4px 0 5px}
.et-podtv .et-lbl{font-variant-numeric:tabular-nums}
.et-cnt{border-radius:999px;padding:2px 8px;font-size:10.5px;font-weight:700;
  font-variant-numeric:tabular-nums}
.et-cnt.sd{background:var(--st-review-bg);color:var(--st-review)}
.et-cnt.vz{background:var(--surface-2);color:var(--danger)}
.et-cnt.bl{background:var(--surface-2);color:var(--ink-2)}
.subs-bar.podtv{height:5px;margin-bottom:11px}
.subs-bar.podtv i{background:var(--st-prog)}
/* чип состояния этапа в строке шага — одно слово */
.et-chip{display:inline-block;margin-left:8px;border-radius:999px;padding:1px 8px;
  font-size:10.5px;font-weight:700;vertical-align:1px;white-space:nowrap}
.et-chip.sd{background:var(--st-review-bg);color:var(--st-review)}
.et-chip.pr{background:var(--st-done-bg);color:var(--st-done)}
.et-chip.vz{background:var(--surface-2);color:var(--danger)}
.et-chip.bl{background:var(--surface-2);color:var(--ink-2)}
/* причина возврата/блока — второй строкой под текстом шага, как подпись who */
.sub-tx .et-why{color:var(--ink-2);text-decoration:none;font-style:italic}
/* sdano/prinyato: галочка снята с руки — строка спокойная, без зачёркивания
   «мышкой нельзя» (замок объясняет тост и чип), курсор обычный */
.sub-row.lock{cursor:default}
.sub-row.lock:hover{background:transparent}
/* серые строки уже сданных/принятых этапов в листе сдачи */
.sd-row.et-ser{opacity:.55}
/* min-height 44px — тач-цель галки это ВСЯ строка (onclick на .sub-row), а не
   квадратик 24px: регламент §3 требует зону касания ≥44, значок остаётся мелким */
/* column-gap, а НЕ gap — см. предупреждение у блока @container shagi выше:
   сокращение gap переписало бы там row-gap:0 и вернуло 11 px на каждый
   двухэтажный шаг. По горизонтали просвет тот же 11 px, что и был. */
.sub-row{display:flex;align-items:center;column-gap:11px;padding:2px 4px;min-height:44px;border-radius:9px;
  cursor:pointer;transition:background .12s}
.sub-row:hover{background:var(--surface-2)}
.sub-box{flex:none;width:24px;height:24px;border-radius:7px;border:2px solid var(--line);
  display:grid;place-items:center;transition:all .2s var(--ease)}
.sub-row.on .sub-box{background:var(--st-done);border-color:var(--st-done);transform:scale(1.06)}
.sub-box svg{width:14px;height:14px;stroke:#fff;fill:none;stroke-width:3;stroke-linecap:round;
  stroke-linejoin:round;opacity:0;transition:opacity .18s}
.sub-row.on .sub-box svg{opacity:1}
/* ═══ СТРОКА ШАГА В ОДИН ЭТАЖ: ИМЯ, ЧИП И «КТО · КОГДА» — ОДНОЙ ЛИНИЕЙ ══════
   «Кто сделал · когда» стояло ОТДЕЛЬНОЙ строкой (display:block) и делало
   сделанный шаг 61 px против 44 у обычного. Список одной высоты читается
   списком; 44/61/92 вперемешку читаются рванью (Material: список одной
   высоты). Ставим в ту же линию мелким, через точку. */
.sub-tx{flex:1;min-width:0;font-size:14px;line-height:1.4;overflow-wrap:anywhere;
  display:flex;align-items:baseline;gap:6px;overflow:hidden}
.sub-tx>.sub-nm{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sub-row.on .sub-tx{color:var(--ink-2);text-decoration:line-through;text-decoration-thickness:1px}
.sub-tx .who{flex:none;font-size:11px;color:var(--ink-2);text-decoration:none;white-space:nowrap}
.sub-tx .et-why{min-width:0;overflow:hidden;text-overflow:ellipsis}
.sub-tx .et-chip{margin-left:0;flex:none}
/* ═══ ДВА ЗНАЧКА В СТРОКЕ ШАГА: САМОЛЁТИК И «⋯» ═════════════════════════════
   Цель 44×44 (§3), рисунок 17 — по соседям: галка 24, крестик был 13.
   ⚠️ НИ ОДИН ИЗ НИХ НЕ ПРЯЧЕТСЯ ПОД НАВЕДЕНИЕ. Крестик стоял opacity:0 и
   проявлялся только на hover — на телефоне это была невидимая 44px-мина,
   лечили её @media(hover:none){opacity:.55}. Здесь лечить нечего: самолётик
   виден полной яркостью всегда (орган, нужный для продолжения работы, обязан
   быть виден по умолчанию — NN/g о таблицах), «⋯» приглушено до .55 и на
   мыши, и на пальце — наведение меняет ТОЛЬКО яркость, не наличие. */
.sub-ic{flex:none;width:44px;height:44px;border-radius:9px;background:transparent;border:0;
  display:grid;place-items:center;cursor:pointer;padding:0;
  transition:background .15s var(--ease),opacity .15s,color .15s}
.sub-ic svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}
.sub-ic:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.sub-send{color:var(--accent);opacity:1}
.sub-send:hover{background:var(--accent-soft);color:var(--accent-hover)}
.sub-mn{color:var(--ink-2);opacity:.55}
.sub-mn svg circle{fill:currentColor;stroke:none}
.sub-mn:hover,.sub-mn:focus-visible,.sub-mn.on{opacity:1;background:var(--surface-2)}
/* меню «⋯» — словами, в потоке под строкой: колонка набора overflow:hidden,
   всплывающий список она обрезала бы (тот же брак, что у листа «Позвать») */
.sub-mnu{display:flex;flex-wrap:wrap;gap:6px;padding:2px 4px 6px 39px}
/* ═══ ПЕРВАЯ СТРОКА МЕНЮ — ПОЛНОЕ ИМЯ ШАГА ══════════════════════════════════
   Единственное место, где имя достаётся ПАЛЬЦЕМ у сделанного и у закрытого
   шага: в строке оно обрезано (.sub-tx>.sub-nm — nowrap + ellipsis), title на
   телефоне не показывается, мини-листа сдачи у таких шагов нет. Замер приёмки
   02.09 на 375/ID: «Saya akan sampaikan kepada GMK…» — видно 110 px из 451,
   24 % строки, и обрезаны были 8 строк из 8.
   ⚠️ НИКАКИХ nowrap, ellipsis И line-clamp ЗДЕСЬ БЫТЬ НЕ МОЖЕТ — это и есть
   тот единственный узел, который обязан показать имя целиком. flex:1 0 100%
   ставит его отдельной строкой над кнопками действий (у .sub-mnu flex-wrap).
   Ворота: проверка «19 ИМЯ» (tests/kartochka_okno.js) жмёт «⋯» и требует, чтобы
   найденный узел с полным именем не был обрезан ни по ширине, ни по высоте. */
.sub-mnu-h{flex:1 0 100%;min-width:0;font-size:12.5px;font-weight:700;color:var(--ink);
  line-height:1.35;padding:2px 0 0;overflow-wrap:anywhere}
.sub-mnu>button{min-height:44px;padding:0 12px;border-radius:9px;border:1px solid var(--line);
  background:var(--surface);color:var(--ink);font:inherit;font-size:12.5px;font-weight:600;
  cursor:pointer;white-space:nowrap}
.sub-mnu>button:hover{background:var(--surface-2)}
.sub-mnu>button.opasno{color:var(--danger)}
.sub-add{display:flex;gap:8px;margin-top:8px}
/* мини-лист сдачи шага: шапка с ПОЛНЫМ именем шага (на телефоне title
   недоступен, а имя в строке обрезано) + поле и самолётик */
.sub-list{flex-direction:column;gap:6px;padding:0 4px 6px}
.sub-list-h{font-size:12px;font-weight:700;color:var(--ink-2);line-height:1.35}
.sub-list-r{display:flex;gap:8px}
.sub-list-r>input{flex:1;min-width:0}
.sub-add input{flex:1;min-width:0;padding:10px 12px;border:1px solid var(--line);border-radius:9px;
  font:inherit;font-size:14px;background:var(--surface);color:var(--ink)}
.sub-add input:focus{outline:none;border-color:var(--accent)}
.sub-add button{min-width:44px;min-height:44px;border-radius:9px;background:var(--surface-2);
  color:var(--accent);font-size:20px;font-weight:700;border:0;cursor:pointer;
  display:grid;place-items:center}
/* стрелка «отправить отчёт» в мини-листе сдачи (эмодзи 📦 убран — регламент §4) */
.sub-add button svg{stroke:currentColor;fill:none;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
.subs-empty{font-size:13px;color:var(--ink-2);padding:2px 4px 8px}
.tc3-fold{border-top:1px solid var(--line);margin-top:14px}
.tc3-fold>summary{list-style:none;cursor:pointer;padding:12px 2px;font-size:11px;font-weight:700;
  letter-spacing:.06em;text-transform:uppercase;color:var(--ink-2);display:flex;align-items:center;gap:8px;min-height:44px}
.tc3-fold>summary::-webkit-details-marker{display:none}
/* ⚠️ SVG в summary ОБЯЗАН иметь размер: без него иконка раздувается в кляксу
   на весь экран (этот баг ловим уже ЧЕТВЁРТЫЙ раз — не удалять правило!) */
.tc3-fold>summary svg{width:14px;height:14px;flex:none;stroke:currentColor;fill:none;
  stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.tc3-menu>summary svg{width:16px;height:16px;flex:none}
.tc3-fold>summary:hover{color:var(--accent)}
.tc3-fold>summary .cnt{margin-left:auto;font-weight:700;color:var(--ink-2)}
.tc3-fold[open]>summary{color:var(--ink)}
.tc3-sheet .btn input[type=file]{display:none}
/* подвал: «⋯» вместо голой красной корзины 50×44 */
.tc3-menu{position:relative;margin-left:auto}
.tc3-menu>summary{list-style:none;cursor:pointer;min-width:44px;min-height:44px;border-radius:var(--r-btn);
  display:grid;place-items:center;font-size:19px;font-weight:700;color:var(--ink-2);background:var(--surface-2)}
.tc3-menu>summary::-webkit-details-marker{display:none}
.tc3-menu[open]>summary{background:var(--accent-soft);color:var(--accent)}
.tc3-menu .mm{position:absolute;right:0;bottom:calc(100% + 6px);background:var(--surface);border:1px solid var(--line);
  border-radius:12px;box-shadow:var(--sh-3);padding:6px;min-width:210px;z-index:5}
.tc3-menu .mm button{width:100%;text-align:left;padding:10px 12px;border-radius:9px;font-size:13.5px;
  font-weight:600;background:none;color:var(--ink);min-height:44px;display:flex;align-items:center;gap:8px}
.tc3-menu .mm button:hover{background:var(--surface-2)}
.tc3-menu .mm button.danger{color:var(--danger)}
.tc3-menu .mm button.danger:hover{background:var(--st-fire-bg)}
.tc3-menu .mm button svg{width:16px;height:16px;flex:none}
.tc3-crumb{display:flex;align-items:center;gap:7px;flex-wrap:wrap;font-size:13px;font-weight:600;position:relative}
.tc3-crumb .sep{color:var(--ink-2);font-weight:400}
.tc3-crumb .soft{color:var(--ink-2);font-weight:500}
/* ── строка «где»: спокойный текст + маленькая кнопка со значком ──
   Было три системные выпадашки подряд — карточка читалась как форма (жалоба
   владельца 11.08). Теперь значение — обычный текст, рядом карандаш, список
   раскрывается на месте силами <details>. */
/* position:relative — ЯКОРЬ СВОЕГО СПИСКА. Было: список якорился ко ВСЕЙ строке
   крошки (.tc3-crumb, left:0;right:0), и три карандаша подряд открывали его в
   ОДНОМ И ТОМ ЖЕ месте — замер 02.09 на 1440: смещение левого края списка от
   своего карандаша −124 (проект), −280 (объект), −378 (этап). Наружу это
   читается как «нажал на этап, а выпало у проекта». Якорь у каждой ячейки свой;
   от правого края список уводит tcPopapVVidu (card.vid.js), а не растяжка. */
.tc3-cell{display:inline-flex;align-items:center;gap:2px;min-width:0;max-width:100%;position:relative}
.tc3-val{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:180px}
/* ⚠️ 44×44 — НАСТОЯЩИЙ размер кнопки, а не увеличенный псевдоэлементом: сторож
   вёрстки меряет сам элемент, и «невидимая область» тач-норму бы не прошла.
   Сам значок 15 px, поэтому в покое кнопка не шумит: фона нет, только иконка. */
.tc3-pick>summary{list-style:none;cursor:pointer;min-width:44px;min-height:44px;
  display:inline-flex;align-items:center;justify-content:center;
  border-radius:var(--r-btn);color:var(--ink-2);background:none;
  transition:background .2s var(--ease),color .2s var(--ease)}
.tc3-pick>summary::-webkit-details-marker{display:none}
.tc3-pick>summary svg{width:15px;height:15px;flex:none;stroke:currentColor;fill:none;
  stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.tc3-pick>summary:hover{background:var(--surface-2);color:var(--accent)}
.tc3-pick[open]>summary{background:var(--accent-soft);color:var(--accent)}
/* ⚠️ ЯКОРЬ ПЕРЕЕХАЛ СО СТРОКИ НА ЯЧЕЙКУ (02.09). Прежний комментарий обещал,
   что растяжка на всю строку спасает последнюю ячейку от правого края, — и
   ценой этого все три списка открывались в одном месте (замер выше, у
   .tc3-cell). За край теперь уводит подводка tcPopapVVidu: она сдвигает
   открытый список внутрь карточки по горизонтали и подводит по вертикали.
   Ширину задаёт сам список, а не строка: min-width обязателен — без него
   список у узкой ячейки («—») схлопнулся бы до ширины слова. */
.tc3-pick .pm{position:absolute;left:0;right:auto;top:calc(100% + 6px);z-index:6;
  min-width:min(240px,86cqw);max-width:min(340px,96cqw);
  background:var(--surface);border:1px solid var(--line);border-radius:12px;
  box-shadow:var(--sh-3);padding:6px;max-height:min(320px,48vh);overflow-y:auto;
  animation:tcPickIn .16s var(--ease)}
@keyframes tcPickIn{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
.tc3-pick .pm .pmh{font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink-2);padding:4px 10px 6px}
.tc3-pick .pm .grp{font-size:10.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
  color:var(--ink-2);padding:10px 10px 4px}
.tc3-pick .pm button{width:100%;text-align:left;padding:10px 12px;border:0;border-radius:9px;
  font-size:13.5px;font-weight:600;background:none;color:var(--ink);min-height:44px;
  display:flex;align-items:center;gap:8px;cursor:pointer;font-family:inherit}
.tc3-pick .pm button:hover{background:var(--surface-2)}
.tc3-pick .pm button .nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tc3-pick .pm button.cur{color:var(--accent)}
.tc3-pick .pm button svg{width:15px;height:15px;flex:none;stroke:currentColor;fill:none;
  stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.tc3-pick .pm button.cur svg{margin-left:auto}
/* правка САМОГО СПИСКА этапов — за чертой и голосом тише: владелец наткнулся на
   «Переименовать», когда просто менял этап */
.tc3-pick .pm .razdel{border-top:1px solid var(--line);margin-top:6px}
.tc3-pick .pm button.act{color:var(--ink-2);font-weight:500}
.tc3-pick .pm button.act:hover{color:var(--accent)}
.tc3-pick .pm .pusto{font-size:12.5px;color:var(--ink-2);padding:4px 10px 10px;line-height:1.35}
/* ── сетка тела v3: лента слева (шире), контекст справа ──
   ⚠️ РАЗВИЛКУ ДЕРЖИТ ШИРИНА САМОЙ КАРТОЧКИ (@container kartochka), А НЕ ОКНА.
   Порог @media(min-width:901px) отвечал на вопрос про устройство и промахивался:
   1280 px при масштабе Windows 150 % — это 853 CSS-px, и сотрудник на обычном
   ноутбуке получал телефонную вёрстку на большом экране. Масштаб меняет и окно,
   и карточку, и кегль одним коэффициентом, поэтому «влезут ли две колонки»
   ширина карточки отвечает честно, а ширина окна — нет.
   Число 760 посчитано от правой колонки: пригодная ширина = контейнер − 36
   (поля .db 2×18), правая колонка максимум 340 + просвет 32, значит ленте на
   пороге остаётся 760 − 36 − 32 − 340 = 352 px. Пузырь реплики 78 % от 352 —
   275 px, строка ещё читается. У сотрудника с 853 px контейнер 810, ленте 402.
   Правая колонка ужата с minmax(300,380) до minmax(280,340) в этой же правке:
   при 380 на пороге ленте оставалось бы 312. Порог и максимум правой колонки —
   одно решение, порознь их назначать нельзя. */
/* ⚠️ КОЛОНКА КОНТЕКСТА СНЯТА НА ВСЕХ ШИРИНАХ (01.09, требование владельца).
   Она перестала быть колонкой и стала свалкой, которую прокручивают вслепую:
   684–2563 px содержимого при 461–488 видимых, у карточки 620 — 983 px слепой
   прокрутки, 2102 с раскрытыми гармошками. 94 органа из 138 лежали в правом
   поле, куда люди приучены не смотреть (NN/g, Right-Rail Blindness), и среди
   них «Удалить навсегда». Весь контекст уехал за одну дверь — в панель
   «Подробно», где у каждой группы есть имя и число в подписи.
   Сетка .tc-grid.v3 оставлена ОДНОЙ колонкой нарочно: по ней меряет сторож
   окна (tests/kartochka_okno.js, проверка 9), и снос обёртки лишил бы ворота
   опоры. Лента получает всю ширину карточки — того же требует общая область
   (NN/g, Common Region): поток и поле, в которое пишут, обязаны читаться как
   один предмет, а лента 982 против поля 1354 читались как два.

   ⚠️ ПЕРЕГИБ ИСПРАВЛЕН 02.09, ТРЕБОВАНИЕ ВЛАДЕЛЬЦА ДОСЛОВНО: «Нахуй нам чат во
   всю страницу? Часть экрана точно нужно использовать под необходимые
   настройки… всё, что нужно по логике, должно остаться на боковой панели».
   Прежняя колонка вернуться не может — она и была свалкой на 94 органа. Вместо
   неё встаёт КОЛОНКА НАБОРА (.tc-col-nabor): приоритет, «в помощь», «следит» и
   шаги — четыре предмета, а не девяносто четыре. За дверью остаётся редкое и
   разрушительное. Правило свалки записано числом в признаках брака: не больше
   трёх предметов плюс список шагов.
   Ширина 320 — Material side sheet 256 dp и отраслевой коридор 280–360; ниже
   строка шага не читается (замер у .subs выше), поэтому список шагов в узкой
   колонке перестроен на два этажа, а не ужат.
   Порог включения — ОДИН НА ДВОИХ с режимом двух портов (@media min-height:800
   ниже): колонка со своей прокруткой имеет смысл только там, где шапка
   закреплена и порт свой у каждой области. Разведи их — на полосе 705–800 svh
   колонка растянулась бы на высоту ленты внутри одного порта, и её содержимое
   уехало бы на тысячи пикселей вверх (болезнь, описанная у снятого блока
   «ДВЕ КОЛОНКИ НА НИЗКОМ ЭКРАНЕ»). Поэтому здесь сетка всегда одна колонка, а
   вторая появляется ровно в одном месте файла — внутри @media(min-height:800px). */
@container kartochka (min-width:760px){
  .task-inline .tc-grid.v3{grid-template-columns:minmax(0,1fr);gap:0}
}
/* ── НАБОР: ЧЕТЫРЕ ПРЕДМЕТА, КОТОРЫЕ ПОД РУКОЙ ─────────────────────────────
   Узел в разметке ОДИН. Второго экземпляра нет и быть не может: внутри лежит
   #subBlockTC, а два узла с одним id — это молча неработающая догрузка шагов.
   Место меняет не JS, а сетка: без второй колонки набор — вторая строка той же
   единственной колонки, то есть блок ПОД лентой (Jira: «context fields …
   or bottom in single-column layout»). Над лентой его ставить нельзя: порт
   наводится на последнюю реплику (card.kommentarii.vid.js, tcKPoslednieReplike),
   и на карточке 787 с 2041 px переписки блок над лентой лежал бы в двух тысячах
   пикселей прокрутки вверх. */
.tc-col-nabor{display:flex;flex-direction:column;gap:0;min-width:0}
.tc-col-nabor .subs{border-top:0;margin-top:0;padding-top:0}
.tc-col-nabor .nab-h{font-size:10.5px;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;color:var(--ink-2);margin:0 0 6px}
/* приоритет правится НА МЕСТЕ: три кнопки выбора вместо четвёртого уровня
   раскрытия (было: дверь → Ещё → Редактировать → select → Сохранить).
   Меньше пяти вариантов — видимые кнопки, а не список (NN/g). */
.nab-prio{display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin:0 0 10px}
.nab-prio .p-b{flex:1 1 auto;min-width:60px;min-height:44px;padding:0 10px;border:0;
  border-radius:10px;background:var(--surface-2);color:var(--ink-2);cursor:pointer;
  font:inherit;font-size:12.5px;font-weight:600;white-space:nowrap}
.nab-prio .p-b:hover{background:var(--accent-soft);color:var(--accent)}
.nab-prio .p-b.on{background:var(--accent-soft);color:var(--accent);box-shadow:inset 0 0 0 1px var(--accent)}
.nab-prio .p-b:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
/* под лентой набор отбит чертой — общая область (NN/g, Common Region): лента и
   поле ответа один предмет, набор другой */
.tc-col-nabor{border-top:1px solid var(--line);margin-top:12px;padding-top:10px}
@container kartochka (max-width:759.98px){
  .task-inline .tc-grid.v3{grid-template-columns:1fr;gap:0;grid-template-rows:auto}
  .task-inline .tc3-top{gap:9px}
  .task-inline .tc3-what h2{font-size:17px}
  /* кольцо срочности на телефоне занимало 56 px в самом дорогом месте экрана */
  .task-inline .tc3-ring .ring{width:44px !important;height:44px !important}
  .task-inline .tc3-ring .ring svg{width:44px;height:44px}
  .task-inline .tc3-ring .ring .pct{font-size:11px}
  .task-inline .tc3-chip .val{max-width:150px}
  .task-inline .tc3-main{width:100%;justify-content:center}
  /* Все четыре шага обязаны быть в карточке СРАЗУ: при min-width:92px полоса
     уезжала в боковую прокрутку (клиент 320 px против 388 px содержимого), и
     «Подтверждено» — шаг, который чаще всего и нужен начальнику — оказывался за
     краем. Подписи переносятся на две строки, это дешевле бокового свайпа.
     Прежние две ступени (@media 900 с min-width:92px и @media 759 с 0) слиты в
     одну: полоса 760–900 px переехала в широкую ветку целиком. */
  .task-inline .cyc{padding:12px 8px}
  .task-inline .cyc-s{min-width:0;padding:5px 4px}
  .task-inline .cyc-s .nm{font-size:11px;line-height:1.25}
}
.who-row{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:14px}
.whochip{display:flex;align-items:center;gap:7px;background:var(--surface-2);border-radius:11px;padding:6px 10px 6px 6px;font-size:12.5px;flex:1;min-width:150px}
.whochip .lbl{color:var(--ink-2);font-size:10.5px;text-transform:uppercase;letter-spacing:.04em;display:block}
.whochip .val{font-weight:600;font-size:13px}
.avatar{width:24px;height:24px;border-radius:999px;background:var(--accent);color:var(--on-accent);display:grid;place-items:center;
  font-size:10.5px;font-weight:700;flex:none}
/* ⚠️ Раньше модификатор назывался .empty и сталкивался с глобальным блоком
   «здесь пусто» (padding:48px) — кружок исполнителя раздувался с 24 до 98 px и
   разносил верх карточки. Имя развели; padding:0 оставлен страховкой. */
.avatar.noone{background:var(--surface);border:1.5px dashed var(--line);color:var(--ink-2);padding:0}
.avatar.sys{background:var(--ink-2)}

/* ── мини-таймлайн задачи: пропорциональный рельс + маркер «сегодня» ── */
.mini-tl{background:var(--surface-2);border-radius:12px;padding:14px 16px 12px;margin:14px 0 0}
.mini-tl .cap{font-size:11px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-2);margin-bottom:6px}
.mini-tl .empty,.mini-tl .tl-empty{font-size:12px;color:var(--ink-2)}
/* пропорциональный трек (абсолютное позиционирование узлов по дням) */
.tl-track{position:relative;height:4px;margin:30px 8px 40px;min-width:0;background:none;border-radius:0}
.tl-base{position:absolute;top:1px;left:0;right:0;height:2px;border-radius:2px;
  background:repeating-linear-gradient(90deg,var(--line) 0 5px,transparent 5px 9px)}
.tl-fill{position:absolute;top:1px;height:2px;border-radius:2px;background:var(--accent)}
.tl-fill.done{background:var(--st-done)}
.tl-fire{position:absolute;top:1px;height:2px;
  background:repeating-linear-gradient(90deg,var(--st-fire) 0 5px,transparent 5px 9px)}
.tl-node{position:absolute;top:-4px;transform:translateX(-50%);width:12px;height:12px;border-radius:50%;
  background:var(--surface);border:2px solid var(--line);box-sizing:border-box;z-index:2}
.tl-node.on{background:var(--accent);border-color:var(--accent)}
.tl-node.done{background:var(--st-done);border-color:var(--st-done)}
.tl-node.fire{background:var(--st-fire);border-color:var(--st-fire)}
.tl-lb{position:absolute;top:14px;transform:translateX(-50%);text-align:center;white-space:nowrap;z-index:1}
.tl-lb .n{display:block;font-size:9px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:var(--ink-2)}
.tl-lb .d{display:block;font-size:10.5px;font-weight:600;margin-top:1px;color:var(--ink)}
.tl-lb.muted .d{color:var(--ink-2);font-weight:500}
.tl-lb.fire .d{color:var(--st-fire)}
.tl-lb.edge-l{transform:none;text-align:left}
.tl-lb.edge-r{transform:translateX(-100%);text-align:right}
.tl-today{position:absolute;top:-25px;transform:translateX(-50%);z-index:3;
  font-size:9px;font-weight:700;color:var(--on-accent);background:var(--accent);padding:2px 7px;border-radius:999px;white-space:nowrap}
.tl-today::after{content:"";position:absolute;bottom:-8px;left:50%;transform:translateX(-50%);width:2px;height:8px;background:var(--accent)}
.tl-today.fire{background:var(--st-fire)}
.tl-today.fire::after{background:var(--st-fire)}
.tl-note{font-size:11px;color:var(--ink-2);margin-top:2px;line-height:1.35}

.sect-lbl{font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-2);
  margin:16px 0 7px;display:flex;align-items:center;gap:6px}
.sect-lbl:first-of-type{margin-top:0}
/* ⚠️ БЕЗ ЯВНОГО РАЗМЕРА браузер раздувает inline-svg до сотен пикселей —
   именно это дважды ломало карточку («иконки-кляксы»). Не удалять. */
.sect-lbl svg,.mat-empty svg,.hist-toggle>svg,.nextstep>svg{
  width:14px;height:14px;flex:0 0 14px;stroke:currentColor;fill:none;stroke-width:2}
.tc-stage-edit{display:inline-block}
.tc-stage-edit select{background:var(--surface-2);border:1px solid var(--line);border-radius:8px;padding:3px 6px;font-size:13px;font-weight:500;color:var(--ink);max-width:160px}
/* select этапа прямо в карточке — раньше был без стиля (системный белый, «жил
   отдельной жизнью»). Приводим к виду карточки. */
/* min-height:44 — этот select был 29 px: одна из четырёх целей первого экрана,
   не проходивших тач-норму (Ю-01). Уплотняем обвязку, а не кнопки. */
.tc-stage-sel{background:var(--surface-2);border:1px solid var(--line);border-radius:8px;
  padding:4px 8px;font-size:13px;font-weight:500;color:var(--ink);max-width:100%;cursor:pointer;font-family:inherit;min-height:44px}
.tc-stage-sel:hover{border-color:var(--accent)}
/* ═══ КАРТОЧКА ЗАДАЧИ — ВСТРОЕНА В СТРАНИЦУ (в потоке, ниже контента) ═══ */
/* overflow:clip, а НЕ hidden: обрезка по скруглению та же, но clip не делает
   элемент портом прокрутки — благодаря этому липкая шапка .tc3-top на узком
   экране (блок v4 внизу файла) липнет к окну страницы, а не к мёртвой обёртке.
   Ровно то, что обещал старый комментарий про несработавшую липкость ниже. */
.task-inline{margin:20px 0 8px;background:var(--surface);border:1px solid var(--line);
  border-radius:16px;box-shadow:var(--sh-2);overflow:clip;
  animation:cardReveal .28s var(--ease)}
@keyframes cardReveal{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
/* Правило липкости .dh-inline убрано: строки .dh в карточке больше нет, но
   липкость не работала и до того — родитель .task-inline имеет overflow:hidden
   (ради скругления 16 px), а любой overflow, кроме visible, делает предка портом
   прокрутки и отменяет sticky. Проверено замером: прокрутка на 500 → шапка
   уехала ровно на 500. Настоящая липкая шапка — отдельная работа: нужен
   overflow:clip либо отказ от обрезки, плюс top:106px и z-index выше 40
   (.hdr страницы — 106 px и z-index:40). Код не должен обещать того, чего нет. */
.task-inline .db{padding:4px 18px 8px}
.task-inline .df{padding:12px 18px;border-top:1px solid var(--line);display:flex;gap:10px;align-items:center}
/* Вторая кнопка закрытия — внизу: 49 % держат телефон одной рукой, и до
   крестика в шапке большой палец не достаёт (UXmatters, 1333 наблюдения). */
.task-inline .tc3-close-bottom{margin-left:auto}
.nextstep{background:var(--accent-soft);border-radius:11px;padding:9px 12px;font-size:12.5px;margin-top:4px;
  display:flex;gap:8px;align-items:flex-start}
.nextstep svg{width:14px;height:14px;margin-top:2px;stroke:var(--accent);fill:none;stroke-width:2;flex:none}
.matlist{display:flex;flex-wrap:wrap;gap:8px;margin-top:2px}
/* ⚠️ min-height 44 — ЭТО ССЫЛКА, А НЕ ПОДПИСЬ. Замер приёмки 02.09 в группе
   ФАЙЛЫ: два a.matchip по 390×29,5 — тач-цель ниже нормы §3 (44), и в описи
   названных исключений (строка адреса 30, #rem_chat 24) их нет. Поднято до
   нормы, а не внесено в исключения: файл открывают пальцем чаще, чем читают
   его имя. Просвет между чипами 8 (.matlist gap) остаётся. */
.matchip{display:flex;align-items:center;gap:6px;background:var(--surface-2);border-radius:10px;
  padding:6px 10px;min-height:44px;font-size:12.5px;color:var(--ink)}
.matchip svg{width:14px;height:14px;stroke:var(--accent);fill:none;stroke-width:2;flex:none}
.mat-empty{font-size:12px;color:var(--ink-2);display:flex;align-items:center;gap:6px}

/* ═════════════ ДОКАЗАТЕЛЬСТВО СДАЧИ ═════════════
   Бэкенд отдаёт has_proof/proof_url у задачи, is_proof у документов и реестр
   /api/materials?task_id= с тегами proof + submit-N. Тип файла заранее НЕ известен
   (акт в pdf — такое же доказательство), поэтому картинка и иконка лежат в одном
   .pfig: img пробует загрузиться, onerror переводит контейнер в .noimg. */
.proofmark{display:inline-flex;align-items:center;gap:5px;font-size:10.5px;font-weight:700;
  background:var(--accent-soft);color:var(--accent);border-radius:999px;padding:2px 9px;margin-bottom:6px;vertical-align:middle}
.proofmark svg{width:12px;height:12px;stroke:currentColor;fill:none;stroke-width:2.1;stroke-linecap:round;stroke-linejoin:round;flex:none}
.proofmark.mini{padding:2px 5px;margin:0 5px 0 0}
.lrow .proofmark.mini,.prow .proofmark.mini{margin-bottom:0}
.pfig .pf-ic{display:none}
.pfig.noimg .pf-ic{display:grid}
.pfig.noimg img{display:none}
.proofbox{margin:14px 0 0;background:var(--surface-2);border-radius:14px;padding:12px 13px;
  border-left:3px solid var(--accent);display:flex;flex-direction:column;gap:10px}
.proofbox .pb-h{display:flex;align-items:center;gap:7px;font-size:10.5px;font-weight:700;
  text-transform:uppercase;letter-spacing:.05em;color:var(--accent)}
.proofbox .pb-h svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2.1;flex:none}
.proofbox .pb-h .pb-n{margin-left:auto;text-transform:none;letter-spacing:0;font-weight:600;color:var(--ink-2)}
.pb-fig{display:block;max-width:340px;border-radius:11px;overflow:hidden;background:var(--surface);
  text-decoration:none;transition:transform .18s var(--ease),box-shadow .18s var(--ease)}
.pb-fig:hover{transform:translateY(-1px);box-shadow:var(--sh-2)}
.pb-fig img{display:block;width:100%;height:auto;max-height:260px;object-fit:cover}
.pb-fig .pf-ic{place-items:center;gap:9px;grid-auto-flow:column;justify-content:start;
  padding:13px 14px;color:var(--ink);font-size:13px;font-weight:600;min-height:44px}
.pb-fig .pf-ic svg{width:22px;height:22px;stroke:var(--accent);fill:none;stroke-width:2;flex:none}
.pb-cap{font-size:13px;color:var(--ink);line-height:1.45;white-space:pre-wrap}
.pb-subs{display:flex;flex-direction:column;gap:9px}
.psub{background:var(--surface);border-radius:11px;padding:9px 11px}
.psub-h{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;font-size:11.5px;font-weight:700;color:var(--ink)}
.psub-h .when{margin-left:auto;font-weight:500;font-size:11px;color:var(--ink-2);white-space:nowrap}
.psub-h .last{font-size:9.5px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;
  color:var(--accent);background:var(--accent-soft);border-radius:999px;padding:1px 7px}
.psub-cap{font-size:12.5px;color:var(--ink-2);line-height:1.4;margin-top:4px;white-space:pre-wrap}
.psub-files{display:flex;flex-wrap:wrap;gap:8px;margin-top:7px}
.pf{display:flex;align-items:center;gap:8px;background:var(--surface-2);border-radius:10px;padding:5px 10px 5px 5px;
  min-height:44px;text-decoration:none;color:var(--ink);max-width:100%;transition:background .18s var(--ease)}
.pf:hover{background:var(--accent-soft)}
.pf .pf-th{flex:none;width:34px;height:34px;border-radius:8px;overflow:hidden;background:var(--surface);color:var(--accent)}
.pf .pf-th img{width:34px;height:34px;object-fit:cover;display:block}
.pf .pf-ic{width:34px;height:34px}
.pf .pf-ic svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;flex:none}
.pf .pf-nm{font-size:12.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:190px}
/* ⚠️ ниже .pf .pf-th img — иначе при равной весомости побеждало бы display:block
   и рядом с иконкой файла висел бы битый квадрат */
.pfig.noimg .pf-th img{display:none}
/* лист сдачи: что реально уйдёт доказательством — вместо исчезающего тоста */
.sub-docs{display:flex;flex-direction:column;gap:7px;margin:2px 0 4px}
.sd-row{display:flex;align-items:center;gap:9px;background:var(--surface-2);border-radius:10px;padding:6px 10px;min-height:44px}
.sd-row input[type=checkbox]{width:20px;height:20px;flex:none;accent-color:var(--accent)}
.sd-row .sd-ic{flex:none;width:26px;height:26px;border-radius:7px;background:var(--surface);display:grid;place-items:center;color:var(--accent)}
.sd-row .sd-ic svg{width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:2;flex:none}
.sd-row .sd-nm{flex:1;min-width:0;font-size:12.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sd-row .sd-tag{flex:none;font-size:10px;font-weight:700;color:var(--accent);background:var(--accent-soft);border-radius:999px;padding:2px 8px}
.sd-note{font-size:11.5px;color:var(--ink-2);line-height:1.4}
.sd-note.warn{color:var(--st-fire)}
/* ═══ «БЕЗ ФОТО» — кнопка-переключатель в листе сдачи ═══
   Базовый .btn ростом 42 px, а закон §3 требует тач-цель ≥44: строка сдачи —
   то место, где бригада жмёт пальцем на солнце, и недобор двух пикселей здесь
   ловил сторож. Поднимаем ростом ВСЕ кнопки этой строки разом, а не одну свою:
   разнокалиберные соседи в одном ряду читаются как поломка. */
.tc3-sheet .sh-row .btn{min-height:44px}
/* нажатое состояние объявлено не только краской: у кнопки стоит aria-pressed,
   а рамка держит признак для тех, кто краску не различает (§1.4.1) */
.sd-bez.on{background:var(--accent-soft);color:var(--accent);
  box-shadow:inset 0 0 0 1.5px var(--accent)}
/* «Фото» при включённом «без фото» — не кнопка, а надпись: цель убрана,
   и вид обязан это показывать, иначе получается мёртвая кнопка */
.btn.ghost.off{color:var(--ink-3);background:var(--surface-2);box-shadow:none;cursor:default}
/* ⚠️ у .sh-l своего правила для svg не было — размер задаём явно и тут, и в атрибутах */
.tc3-sheet .sh-l svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2;vertical-align:-2px;margin-right:4px}

/* ═══ ЛИСТ СДАЧИ: СВЁРНУТЫЕ СПИСКИ ═══════════════════════════════════════════
   Число, на котором обожглись: 852 px листа на экране 900 (карточка 620, четыре
   готовых этапа и шесть файлов) — от чата не оставалось ничего, а на 375 лист
   рос до 952 и кнопка «Отправить» уходила за экран. Два списка стоили 602 px из
   852. Свёрнуты, состояние сказано числом в подписи — разворачивать надо только
   тому, кто и правда меняет выбор. */
.sd-fold{background:var(--surface);border:1px solid var(--line);border-radius:10px}
.sd-fold>summary{list-style:none;cursor:pointer;min-height:44px;padding:0 10px;
  display:flex;align-items:center;gap:8px;font-size:12px;color:var(--ink-2)}
.sd-fold>summary::-webkit-details-marker{display:none}
.sd-fold>summary:hover{color:var(--accent)}
.sd-fold>summary .sd-fl{flex:none;font-size:10.5px;font-weight:700;letter-spacing:.05em;
  text-transform:uppercase;color:var(--ink-2);display:flex;align-items:center;gap:5px}
.sd-fold>summary .sd-fc{flex:1;min-width:0;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* ⚠️ SVG в summary ОБЯЗАН иметь размер — иначе иконка раздувается в кляксу (§4) */
.sd-fold>summary svg{width:13px;height:13px;flex:none;stroke:currentColor;fill:none;
  stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.sd-fold[open]>summary{color:var(--ink);border-bottom:1px solid var(--line)}
.sd-fold[open]>summary>svg{transform:rotate(180deg)}
.sd-fold .sub-docs{margin:8px;gap:6px}
/* строка вместо списка там, где списка нет: «файл необязателен», «нет готовых» */
.sd-line{display:flex;align-items:center;gap:6px;padding:2px;font-size:11.5px;
  line-height:1.4;color:var(--ink-2)}
.sd-line svg{width:13px;height:13px;flex:none;stroke:currentColor;fill:none;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
/* подсказка микрофона — пустая коробка в колонке всё равно берёт отступ */
.tc3-sheet .mic-hint:empty{display:none}
/* факт · Фото · Без фото — одной строкой и на телефоне: поле ужимается, кнопки нет */
.sd-strip{flex-wrap:nowrap}
/* поле факта — орган управления: рост не мельче тач-нормы 44 (§3) */
.sd-strip>input{flex:1 1 64px;width:auto;min-width:0;max-width:220px;min-height:44px}
.sd-strip>.btn{flex:none;padding:0 12px}
/* отправка и отмена — рядом, а не в два этажа: общее правило телефона растягивает
   .tc3-main на всю ширину, и кнопка отмены уезжала на второй этаж (+53 px) */
.sd-send{flex-wrap:nowrap}
@container kartochka (max-width:759.98px){
  .task-inline .tc3-sheet .sd-send .tc3-main{width:auto;flex:1;justify-content:center;padding:0 14px}
  .task-inline .sd-strip>.btn{padding:0 10px}
}

/* ═════════════ КАРТОЧКА ЗАДАЧИ: обсуждение (комментарии) — «карточка-ядро»,
   ключевой пункт владельца. Лента + форма ввода, задача_id из URL /api/tasks/{id}/comments. ═════════════ */
.tc-comments{margin-top:2px}
/* ЛЕНТА РЕПЛИК СВОЕГО ПОТОЛКА НЕ ИМЕЕТ — ЕЙ ЕГО ДАЁТ ОКНО КАРТОЧКИ.
   ⚠️ Запрет «ставить сюда потолок обратно — брак», стоявший здесь с 31.08,
   ОТМЕНЁН словом владельца 01.09: «чтобы у нас был комфортный размер окна для
   карточки; размер чата — чтобы он прокручивался и карточка не росла от чата».
   Оба прежних решения — про одно и то же: своего потолка `max-height:52vh` у
   ленты быть не должно, потому что он держал её в щель, пока страница внизу
   пустовала. Высоту лента получает СНАРУЖИ, от окна карточки (--kartochka-окно,
   блок «ОКНО КАРТОЧКИ» внизу файла): на широкой карточке высокого экрана лента
   сама становится окном (flex:1 + overflow-y:auto), в остальных случаях её
   листает порт карточки. Своё число сюда не возвращать ни в каком виде. */
.tc-comments-list{display:flex;flex-direction:column;gap:10px;margin-bottom:10px}
/* ⚠️ overscroll-behavior:contain СНЯТ 01.09 И ВОЗВРАЩАТЬ ЕГО СЮДА НЕЛЬЗЯ.
   Владелец дословно: «дочитал чат до конца — страница дальше не листается».
   contain — это ПРЯМОЙ ЗАПРЕТ продолжить прокрутку странице, и он оправдан
   только у всплывающего окна поверх экрана (шторка, модалка), где под ним
   лежит чужой экран. Лента реплик — часть страницы: докрутил её до низа —
   тем же движением обязана поехать страница. Стоял он тут с тех времён, когда
   у ленты был потолок 440 px; потолок сняли 31.08, а запрет забыли. */
/* свои/чужие — как в мессенджерах (владелец, 16.08): своё вправо и залито
   акцентом приглушённо, чужое влево на поверхности карточки; имя автора — только
   у чужих. align-self решает сторону прямо на плитке — список уже flex-column,
   обёртка не нужна. Пузырь не шире 78%, иначе стороны не читаются. */
.tc-comment{max-width:78%;background:var(--card);border:1px solid var(--line);border-radius:12px;padding:9px 11px}
/* ⚠️ ПУЗЫРЬ С ОРГАНАМИ НЕ ИМЕЕТ ПРАВА БЫТЬ УЖЕ СВОЕЙ ШАПКИ — И ЭТО НЕ ЧИСЛО.
   Замер 02.09, 375 px, полоса реплик 296: в строке «кто · когда» СВОЕЙ реплики
   шесть предметов, и три не сжимаются никогда (значок цикла 22 + правка 44 +
   удалить 44 — тач-норма §3), плюс «перевод» 71 и время 45. Шапке нужно 254,
   а 78 % полосы давали пузырю 231 и содержимому 205: крестик удаления вылезал
   за правый край пузыря на 26 px, и порт ленты .tc-port ехал вбок ровно на эти
   26 на четырёх карточках стенда из девяти (617, 787, 358, 725). Обрезкой это
   не лечится — §10 запрещает и прокрутку, и клип. Пузырю разрешено раздвинуться
   ровно на столько, сколько просит его собственная шапка: мера min-content, а
   не пиксели, потому что у ID слова другой длины. Замер после: своя реплика
   растёт с 231 до 261,7 (ID — 233,2), отступ слева остаётся 32 px, стороны
   по-прежнему читаются, горизонталь 0 на всех девяти карточках.
   ⚠️ :has(.del), А НЕ ПРОСТО .tc-comment — иначе min-content хватает и чужие
   пузыри с блоком действия, и они распухают до полной полосы без всякой на то
   причины (проверено: 287,7 и 294 на 358 и 658). Органы стоят только у своих,
   значит и право раздвинуться — только у своих. */
.tc-comment:has(> .tc-comment-h > .del){min-width:min-content}
.tc-comment.theirs{align-self:flex-start}
.tc-comment.mine{align-self:flex-end;background:var(--accent-soft);border-color:transparent}
/* ⚠️ СТРОКА «КТО · КОГДА» РАЗДВИНУТА ПОД ТАЧ-ЦЕЛЬ. В ней живут две кнопки —
   «оригинал/перевод» и крестик удаления, — и обе обязаны быть 44 px (регламент
   §3). Пока строка была двадцатипиксельной, кнопки либо оставались мелкими
   (сторож: 16 мелких целей на карточке), либо вылезали за строку и накрывали
   текст реплики (сторож: 3 наложения). Оба состояния — брак. Даём строке
   настоящую высоту: кнопки встают внутрь, наложений нет, палец попадает. */
.tc-comment-h{display:flex;align-items:center;gap:7px;margin-bottom:3px;min-height:44px}
.tc-comment-h .who{font-size:12.5px;font-weight:700}
.tc-comment-h .when{font-size:10.5px;color:var(--ink-2);margin-left:auto}
/* ⚠️ «оригинал»/«asli» — ШИРИНА ТОЖЕ 44, НЕ ТОЛЬКО РОСТ. base.css даёт .tr-btn
   рост 44 и поля 0 12, а ширину оставляет слову: по-индонезийски «asli» — четыре
   буквы, и коробка выходила 42.3×44. Сторож вёрстки печатал недобор на 375, 853,
   1024 и 1440 (замер 03.09, карточки 620 и 715). Правим ЗДЕСЬ, а не в base.css:
   правило действует только внутри карточки, чужой чат не задето. */
.task-inline .tc-comment-h .tr-btn{min-width:44px;justify-content:center}
/* Крестик удаления реплики — тач-цель 44, значок внутри прежний, 13 px. */
.tc-comment-h .del{flex:none;width:44px;height:44px;
  border-radius:10px;color:var(--ink-2);display:grid;place-items:center}
.tc-comment-h .del:hover{background:var(--surface);color:var(--st-fire)}
.tc-comment-h .del svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2}
/* Карандаш правки — ровно тот же размер и вес, что крестик: две кнопки в строке
   должны читаться парой, а не «главная и приклеенная». Тач-цель те же 44.
   Имени даём сжиматься (min-width:0 + многоточие): две кнопки справа съели
   место, и длинное имя иначе вылезало бы за край — брак по сторожу вёрстки. */
.tc-comment-h .edt{flex:none;width:44px;height:44px;
  border-radius:10px;color:var(--ink-2);display:grid;place-items:center}
.tc-comment-h .edt:hover{background:var(--surface);color:var(--accent)}
.tc-comment-h .edt svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
.tc-comment-h .who{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Поле правки — на месте реплики, чтобы глаз не искал, куда её унесли. */
.tc-cmt-ed{display:flex;flex-direction:column;gap:6px;margin:2px 0 4px}
.tc-cmt-ta{width:100%;box-sizing:border-box;font:inherit;font-size:13px;line-height:1.45;
  padding:8px 10px;border:1px solid var(--line);border-radius:10px;
  background:var(--surface);color:var(--ink);resize:vertical;min-height:64px}
.tc-cmt-ta:focus{outline:none;border-color:var(--accent)}
.tc-cmt-eact{display:flex;gap:8px}
.tc-cmt-eact button{min-height:44px;padding:0 16px;border-radius:10px;font-size:12.5px;font-weight:700;
  border:1px solid var(--line);background:var(--surface);color:var(--ink);cursor:pointer}
.tc-cmt-eact .ok{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
.tc-comment-txt{font-size:13px;line-height:1.45;white-space:pre-wrap;word-break:break-word}

/* ═════════ РЕПЛИКИ ЦИКЛА И ПРИЁМКА НА САМОМ СООБЩЕНИИ (жалоба 31.08) ═════════
   Сдача, возврат и приёмка приезжают в ленту обычными комментариями с пометкой
   source (сервер, _add_cycle_comment). Раньше фронт её не читал, и сдачу
   приходилось дублировать плашкой над чатом. Теперь смысл несёт левая грань
   цветом стадии и значок — без крика и без единого нового слова («Тихая доска»:
   иерархия тоном и пространством, не рамками и не заливкой). */
.tc-comment.cycm{border-left:3px solid var(--line)}
.tc-comment.cycm-submit{border-left-color:var(--st-review)}
/* возврат — это переход В РАБОТУ, поэтому и цвет статуса «в работе».
   Терракота сюда не годится: §1, терракота — канал СРОКА и статусный
   цвет собой не подменяет. */
.tc-comment.cycm-return{border-left-color:var(--st-prog)}
.tc-comment.cycm-confirm{border-left-color:var(--st-done)}
.tc-comment .cycm-ic{flex:none;width:22px;height:22px;border-radius:7px;display:grid;place-items:center;
  background:var(--surface-2);color:var(--ink-2)}
.tc-comment.cycm-submit .cycm-ic{background:var(--st-review-bg);color:var(--st-review)}
.tc-comment.cycm-return .cycm-ic{background:var(--st-prog-bg);color:var(--st-prog)}
.tc-comment.cycm-confirm .cycm-ic{background:var(--st-done-bg);color:var(--st-done)}
.tc-comment .cycm-ic svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}
/* сообщение, на котором висит приёмка, — во всю ширину ленты: пузырь в 78 %
   ломал бы пару кнопок на второй этаж и лист выбора этапов вместе с ней */
.tc-comment.has-act{max-width:100%;align-self:stretch}
.cmt-priyom{margin-top:8px;padding-top:8px;border-top:1px solid var(--line);
  display:flex;flex-direction:column;gap:8px}
.cmt-act{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
/* «гигантских кнопок сверху» больше нет: пара живёт в реплике и ростом ровно в
   тач-норму 44, а не 52, как крупное действие карточки */
.cmt-act .tc3-main{min-height:44px;padding:0 18px;font-size:13.5px;box-shadow:none}
/* на телефоне общее правило растягивает .tc3-main на всю ширину — там это
   верно для крупного действия карточки, но пара в реплике от этого встаёт в
   два этажа. В реплике кнопки остаются рядом. */
@container kartochka (max-width:759.98px){ .task-inline .cmt-act .tc3-main{width:auto;justify-content:flex-start} }
.cmt-act .tc3-second{min-height:44px}
.cmt-priyom .tc3-sheet{background:var(--surface)}
.cmt-priyom .et-pr-sheet{padding:9px 11px}

.tc-comments-empty{font-size:12px;color:var(--ink-2);padding:2px 0 4px}
.tc-comments-loading{font-size:12px;color:var(--ink-2)}
/* ═══ ПОЛОСА ОТВЕТА: ПОЛЕ — ПЕРВЫЙ ЭТАЖ, ОРГАНЫ — ВТОРОЙ ═══════════════════
   Требование владельца 01.09 дословно: «Строка написания текста — во всю длину
   карточки!»
   ЧТО БЫЛО. display:flex в один ряд, три соседа со flex:none (скрепка 44,
   микрофон 44, «Отправить» 104) и три зазора по 8 — 216 px из 305 на 375, то
   есть 71 % строки. Полю доставался ОСТАТОК: 89 px на 375 и 1138 из 1390 на
   1440. Ширина поля — сигнал об ожидаемом вводе; фиксированную ширину дают
   только вводу известной длины — индексу, телефону (GOV.UK Text input,
   Baymard «Form field usability»). Поле произвольной длины остатком быть не
   может по правилу, а не по вкусу.
   ЧТО СТАЛО. Поле занимает 100 % внутренней зоны формы на обеих ширинах;
   вложения слева, отправка справа — этажом ниже (MUI Chat Composer; так же
   стоят Slack, GitHub, Jira, Basecamp).
   ЧЕМ ЗАПЛАТИЛИ. Полоса выросла: платит лента. Поле держим в ОДНУ строку по
   умолчанию (rows="1", min-height 44) и с потолком роста — иначе набор в три
   строки съедал бы третью реплику и порог §6.2 не брался бы на 375. */
/* ═══ 02.09: ЭТАЖ СНОВА ОДИН, И ЭТО НЕ ОТКАТ, А ДРУГАЯ АРИФМЕТИКА ═══════════
   Правило то же, что 01.09: органы в строке не больше трети её ширины. Тогда
   их было ЧЕТЫРЕ (скрепка 44 + микрофон 44 + «Отправить» 104 + полка 76 и три
   зазора = 216 из 305 = 71 %) — второй этаж был обязателен. Теперь их ДВА:
   скрепка и одна ячейка (микрофон ⇄ самолётик), 88 из 296 = 30 %. Полка уехала
   в строку «Дело», слово «Отправить» — в подсказку значка.
   Неснимаемое в строке: набивка 3+3, две цели 44+44, два зазора 2+2 = 98.
   Полоса в покое 103 → 53 px (8 набивки + 44 поля + 1 грань), ленте +50. */
.tc-comment-form{display:flex;flex-direction:row;gap:2px;align-items:flex-end;padding:0 3px}
.tc-comment-form textarea{flex:1 1 auto;min-width:0;min-height:44px;max-height:96px;resize:none;
  border:1px solid var(--line);
  border-radius:11px;background:var(--surface);padding:11px 12px;font-size:13px;line-height:1.4;box-sizing:border-box}
.tc-comment-form textarea:focus{border-color:var(--accent)}
/* ЯЧЕЙКА СПРАВА — ОДНА КОРОБКА 44×44 НА ДВА СОСТОЯНИЯ. Оба значка лежат друг
   на друге (position:absolute), поэтому смена состояния не двигает поле ни на
   пиксель: §8 стиля запрещает перекладку под руками. */
.tc-comment-form .cmt-yach{flex:none;position:relative;width:44px;height:44px}
.tc-comment-form .cmt-yach>.mic-s,.tc-comment-form .cmt-yach>.cmt-send{position:absolute;inset:0;margin:0}
.tc-comment-form.est-tekst .cmt-yach>.mic-s{display:none}
.tc-comment-form:not(.est-tekst) .cmt-yach>.cmt-send{display:none}
/* ⚠️ ПОКА ИДЁТ ЗАПИСЬ — МИКРОФОН ВИДЕН, ЧЕМ БЫ ПОЛЕ НИ БЫЛО ЗАПОЛНЕНО.
   Voice.paint() красит кнопку по [data-mic] классом .rec, и это единственный
   видимый признак того, что запись идёт. Спрятать его под «есть текст» значило
   бы записывать вслепую: расшифровка приходит уже после stop, и человек не
   видел бы, что микрофон вообще включён (Voice.fill ДОПИСЫВАЕТ к набранному). */
.tc-comment-form.est-tekst .cmt-yach>.mic-s.rec{display:grid}
.tc-comment-form .cmt-yach:has(>.mic-s.rec)>.cmt-send{display:none}
/* САМОЛЁТИК: значок 19 — ровно как у скрепки и микрофона (строка читается как
   одна), цель полная 44×44. Цвет только из переменных: в тёмной теме
   --accent уже голубой (#7CA0C4), в светлой сине-стальной (#3B5B7A). */
.cmt-send{flex:none;width:44px;height:44px;border-radius:12px;border:0;background:transparent;
  color:var(--accent);display:grid;place-items:center;cursor:pointer;padding:0;
  transition:background .18s var(--ease),color .18s var(--ease),transform .18s var(--ease)}
.cmt-send svg{width:19px;height:19px;stroke:currentColor;fill:none;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
.cmt-send:hover{background:var(--accent-soft);color:var(--accent-hover)}
.cmt-send:active{transform:scale(.9)}
.cmt-send:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.cmt-send:disabled{opacity:.45;cursor:default}
/* СКРЕПКА в строке комментария — с другой стороны от «Отправить». Значок маленький
   (19 px), а цель полная 44×44: просьба владельца «аккуратная кнопочка» не отменяет
   тач-норму. Размеры и повадки те же, что у .mic-s, чтобы строка читалась как одна. */
.cmt-clip{flex:none;width:44px;height:44px;border-radius:12px;background:var(--surface-2);
  display:grid;place-items:center;color:var(--ink-2);cursor:pointer;
  transition:background .18s var(--ease),color .18s var(--ease),transform .18s var(--ease)}
.cmt-clip:hover{background:var(--accent-soft);color:var(--accent)}
.cmt-clip:active{transform:scale(.9)}
.cmt-clip svg{width:19px;height:19px;stroke:currentColor;fill:none;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
.cmt-clip input{display:none}
/* ВЛОЖЕНИЕ В РЕПЛИКЕ ЧАТА — плитка РОВНО ВДВОЕ МЕНЬШЕ, чем в блоке документов:
   миниатюра 22 px против 44 px («в два чуть меньше»). Тач-цель у ссылки полная.
   Картинка и иконка лежат в одном .pfig, как у доказательства: тип файла заранее
   не известен, onerror переводит контейнер в .noimg и показывает значок. */
.cmt-file{display:inline-flex;align-items:center;gap:7px;min-height:44px;max-width:100%;
  background:var(--surface-2);border-radius:10px;padding:4px 10px 4px 4px;
  text-decoration:none;color:var(--ink);transition:background .18s var(--ease)}
.cmt-file:hover{background:var(--accent-soft)}
.cmt-file.nolink{cursor:default}
/* ⚠️ 22 → 44 (02.09). «Иконки небольшие» владелец сказал про АЛЬБОМ; про
   одиночное вложение он сказал «предпросмотр быть должен», а в 22 px не
   разобрать ничего. 44 — та же миниатюра, что в блоке документов, и та же
   тач-норма §3. Цена названа: одиночная реплика 111 → ~119 px. */
.cmt-file{border:0;font:inherit;text-align:left;cursor:pointer}
.cmt-file .cf-th{flex:none;position:relative;width:44px;height:44px;border-radius:8px;overflow:hidden;
  background:var(--surface);color:var(--accent)}
.cmt-file .cf-th img{position:relative;z-index:1;width:44px;height:44px;object-fit:cover;display:block;
  background:var(--surface)}
/* значок типа — подложкой под картинкой, а не вместо неё: та же причина, что у
   .doc-th в screens.css (ленивая картинка не оставляет пустого квадрата) */
.cmt-file .cf-th .pf-ic{display:grid;position:absolute;inset:0;width:44px;height:44px;place-items:center}
.cmt-file .cf-th .pf-ic svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:2;flex:none}
.cmt-file .cf-nm{font-size:12.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* ═══ АЛЬБОМ: ПЛИТКА = ТРЕТЬ АЛЬБОМА, ДВА РЯДА ПОТОЛОК ══════════════════════
   Пузырь альбома шире обычных 78 %: при 78 % на 375 содержимого остаётся 207,
   и плитка вышла бы 65 px — меньше тач-нормы. Потолок 340 даёт 86 px на 375 и
   101 на 1440 при одном правиле «треть альбома», а не двух числах.
   Два ряда — не вкус: реплика не имеет права сломать «три реплики в виду при
   проёме ≥560» (проверка 4 сторожа окна). */
/* ⚠️ width, А НЕ ТОЛЬКО max-width. Пузырь в ленте меряется по содержимому, а
   содержимое альбома — сетка repeat(3,1fr) с aspect-ratio: без заданной ширины
   она схлопывается в min-content, и замер 02.09 на 622 дал пузырь 175 и плитку
   46 вместо 340 и 101. Ширина задаётся ОДНИМ правилом «треть альбома», отсюда
   86 на 375 и 101 на 1440 — два числа из одной формулы, а не два числа. */
.tc-comment.albom{width:min(340px,100%);max-width:min(340px,100%)}
.tc-comment.albom .tc-comment-h{min-height:26px;margin-bottom:5px}
.cmt-albom{display:grid;grid-template-columns:repeat(3,1fr);gap:6px}
.alb-p{position:relative;aspect-ratio:1/1;border:0;padding:0;border-radius:9px;overflow:hidden;
  background:var(--surface);cursor:pointer;display:block}
.alb-p>.pfig{position:absolute;inset:0;display:block;color:var(--accent)}
.alb-p img{position:relative;z-index:1;width:100%;height:100%;object-fit:cover;display:block}
.alb-p .pf-ic{position:absolute;inset:0;display:grid;place-items:center}
.alb-p .pf-ic svg{width:22px;height:22px;stroke:currentColor;fill:none;stroke-width:2}
.alb-p:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.alb-p .alb-n{position:absolute;inset:0;z-index:2;display:grid;place-items:center;
  background:rgba(0,0,0,.45);color:#fff;font-size:15px;font-weight:700}
/* ═══ ПРОСМОТРЩИК ФОТО — ОКНО ПОВЕРХ ЭКРАНА ═════════════════════════════════
   Единственное место карточки, где overscroll-behavior:contain законен: §8
   стиля разрешает его всплывающему окну, под которым лежит чужой экран. */
/* 90 — выше окна сдачи (--z-kartokno 86) и ниже тоста (100): снимок открывают
   и при открытом окне сдачи, и он обязан лечь поверх него, а не под ним */
/* ⚠️ ПРЕФИКС `fsm-`, А НЕ `fs-`, И ЭТО НЕ ВКУСОВЩИНА — ЭТО ПОЧИНЕННЫЙ БРАК.
   Первая версия звала органы шапки `fs-b`/`fs-nm`/`fs-x`. Имя `.fs-b` уже
   занято файловым экраном: `frontend/css/screens.css:724` объявляет
   `.fs-b{width:36px;height:36px}` — значок 36×36. `screens.css` подключается
   ПОСЛЕ `card.css`, ширина в карточке не объявлялась вовсе, и правило чужого
   экрана перебивало наше молча: ссылка «Открыть оригинал» получала коробку
   36 px при содержимом 68 (scrollWidth 68 / clientWidth 36), текст переносился
   в две строки и ложился на крестик закрытия с наложением ≈24 px. Просмотрщик
   был сломан на ВСЕХ ширинах, а сторож вёрстки этого не видел: крестик
   объявлен `background:transparent`, а сторож сравнивает текст только с
   коробками, у которых есть фон или рамка.
   ПРАВИЛО НА БУДУЩЕЕ: имя класса выбирается ГРЕПОМ ПО ВСЕМ ТАБЛИЦАМ
   (`grep -rn "\.имя\b" frontend/css/`), а не на слух и не грепом по одному
   card.css — соседний файл перебьёт незамеченным. `fsm-` проверен: во всём
   frontend его не было ни разу.
   Брак нашла приёмка → в ворота заведена проверка «20 СМОТР»
   (tests/kartochka_okno.js): органы шапки не обрезаны (scrollWidth ≤ clientWidth)
   и не мельче 44. На старых именах она красная. */
.fotosmotr{position:fixed;inset:0;z-index:90;background:rgba(0,0,0,.86);
  display:flex;flex-direction:column;overscroll-behavior:contain}
.fotosmotr .fsm-shapka{flex:none;display:flex;align-items:center;gap:8px;padding:6px 10px;color:#fff}
.fotosmotr .fsm-nm{font-size:12.5px;font-weight:600;min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.fotosmotr .fsm-sch{font-size:11.5px;opacity:.7;flex:none;font-variant-numeric:tabular-nums}
/* width:auto и min-width:44 объявлены ЯВНО, хотя auto и так подразумевается:
   молчание в этом месте и стоило нам чужих 36 px (см. предупреждение выше). */
.fotosmotr .fsm-b{flex:none;margin-left:auto;width:auto;height:auto;min-width:44px;min-height:44px;
  display:inline-flex;align-items:center;
  padding:0 12px;border:0;border-radius:9px;background:rgba(255,255,255,.14);color:#fff;
  font:inherit;font-size:12.5px;font-weight:600;text-decoration:none;cursor:pointer;white-space:nowrap}
.fotosmotr .fsm-b+.fsm-b{margin-left:0}
.fotosmotr .fsm-b.opasno{color:var(--alarm-line)}
.fotosmotr .fsm-x{flex:none;width:44px;height:44px;border:0;border-radius:9px;background:transparent;
  color:#fff;display:grid;place-items:center;cursor:pointer}
.fotosmotr .fsm-x svg{stroke:currentColor;fill:none;stroke-width:2.2;stroke-linecap:round}
.fotosmotr .fsm-telo{flex:1 1 auto;min-height:0;position:relative;display:grid;place-items:center;padding:0 8px}
.fotosmotr .fsm-big{max-width:100%;max-height:100%;object-fit:contain;display:block}
.fotosmotr .fsm-str{position:absolute;top:50%;transform:translateY(-50%);width:44px;height:44px;
  border:0;border-radius:50%;background:rgba(255,255,255,.16);color:#fff;display:grid;place-items:center;cursor:pointer}
.fotosmotr .fsm-str.l{left:6px} .fotosmotr .fsm-str.r{right:6px}
.fotosmotr .fsm-str svg{stroke:currentColor;fill:none;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
.fotosmotr .fsm-lenta{flex:none;display:flex;gap:6px;padding:8px 10px;overflow-x:auto}
.fotosmotr .fsm-m{flex:none;width:52px;height:52px;border:2px solid transparent;border-radius:8px;
  overflow:hidden;padding:0;background:none;cursor:pointer}
.fotosmotr .fsm-m.on{border-color:var(--accent)}
.fotosmotr .fsm-m img{width:100%;height:100%;object-fit:cover;display:block}
.hist-toggle{width:100%;display:flex;align-items:center;gap:8px;padding:13px 4px;margin-top:6px;border-top:1px solid var(--line);
  font-size:13px;font-weight:600;color:var(--ink);min-height:44px}
.hist-toggle .cnt{background:var(--surface-2);color:var(--ink-2);font-size:11px;font-weight:700;padding:2px 8px;border-radius:999px}
.hist-toggle .chev{margin-left:auto;transition:transform .2s var(--ease)}
.hist-toggle .chev svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2}
.hist-toggle.open .chev{transform:rotate(180deg)}
/* Потолок раскрытой панели ставит JS по фактическому содержимому
   (tcHistVysota в card.vid.js). Здесь остаётся только закрытое состояние и сам
   переход. Число 900px, стоявшее тут раньше, резало длинную историю молча. */
.hist-panel{overflow:hidden;max-height:0;transition:max-height .3s var(--ease)}
.hist-panel.open{max-height:none}
.hist-inner{padding:12px 2px 4px}
.stepper{display:flex;align-items:center;padding:4px 4px 14px}
.step{display:flex;flex-direction:column;align-items:center;flex:none;position:relative}
.step .pt{width:11px;height:11px;border-radius:999px;background:var(--line);border:2px solid var(--surface);
  box-shadow:0 0 0 1.5px var(--line)}
.step.done .pt{background:var(--st-done);box-shadow:0 0 0 1.5px var(--st-done)}
.step.fire .pt{background:var(--st-fire);box-shadow:0 0 0 1.5px var(--st-fire)}
.step .lbl{font-size:10px;color:var(--ink-2);margin-top:6px;white-space:nowrap;text-align:center}
.step .dt{font-size:9.5px;color:var(--ink-2);opacity:.85}
.tc-seg{flex:1;height:2px;background:var(--line);margin:0 -1px;min-width:16px}
.tc-seg.done{background:var(--st-done)}
.tc-seg.fire{background:repeating-linear-gradient(90deg,var(--st-fire) 0 5px,transparent 5px 9px)}
.tc-seg.open{background:repeating-linear-gradient(90deg,var(--line) 0 5px,transparent 5px 9px)}
.tc-hist-e{display:flex;gap:9px;padding:8px 0;border-bottom:1px solid var(--line)}
.tc-hist-e:last-child{border-bottom:none}
.tc-hist-e .hi{width:24px;height:24px;border-radius:999px;background:var(--surface-2);display:grid;place-items:center;flex:none}
.tc-hist-e .hi svg{stroke:var(--accent);width:12px;height:12px;fill:none;stroke-width:2}
/* В строке истории теперь стоит имя приложенного файла, а оно бывает без единого
   пробела («Screenshot_2026_08_10_143440_com_whatsapp.jpg») и вылезало за правый
   край карточки. Перенос по любому месту — только здесь, слов это не касается. */
.tc-hist-e .htxt{font-size:13px;line-height:1.4;overflow-wrap:anywhere;min-width:0}
.tc-hist-e .htxt b{font-weight:600}
.tc-hist-e .hwhen{font-size:11px;color:var(--ink-2);margin-top:1px}
.hist-empty2{font-size:12.5px;color:var(--ink-2);display:flex;gap:8px;align-items:flex-start;padding:4px 0}
.hist-empty2 svg{margin-top:2px;flex:none;width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:2}
.hist-loading2{font-size:12.5px;color:var(--ink-2);padding:4px 0}

/* ═════════════ карточка задачи ПОД кликнутой строкой (в т.ч. в узкой колонке канбана) ═════════════ */
.task-inline{width:100%}
.col .task-inline{margin:10px 0}
.col .task-inline .tc-grid{grid-template-columns:1fr}
.col .task-inline .tc-band{flex-wrap:wrap}
.col .task-inline .tc-band-left{max-width:none;flex:1 1 100%}
.col .task-inline .tc-band-right{flex:1 1 100%;flex-wrap:wrap;justify-content:center}
.col .task-inline .tc-state-stack .statusbtns{width:auto}
.col .task-inline .tc-state-stack .statusbtns button{min-width:0}
.col .task-inline .db{padding:4px 12px 8px}
.col .task-inline .df{padding:10px 12px;flex-wrap:wrap}
.searchres .task-inline,.ltable .task-inline{margin:10px 0}

/* ═════════════ inline-редактирование карточки (поля на месте, без отдельной формы) ═════════════ */
.ie-title,.ie-trans,.ie-input{border:1px solid var(--line);border-radius:9px;background:var(--bg);padding:7px 10px;font-size:14px;width:100%;box-sizing:border-box}
.ie-title{font-size:18px;font-weight:600}
.ie-trans{margin-top:6px;color:var(--ink-2)}
.ie-title:focus,.ie-trans:focus,.ie-input:focus{border-color:var(--accent);outline:none}
.kv .ie-input{width:auto;flex:1;min-width:0}
textarea.ie-input{min-height:56px;resize:vertical;font-family:inherit;line-height:1.4}
.whochip .ie-input{padding:5px 8px;font-size:13px}

/* ═════════════ напоминание в карточке (Контракт 4) ═════════════ */
.remrow{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:2px}
/* тач-норма 44 px: было 38 у полей и кнопки и 15×15 у галки — галка не проходила
   даже минимум WCAG 2.5.8 (24×24). Целью нажатия служит вся подпись .remchk. */
.remrow input[type=date],.remrow input[type=time]{height:44px;border:1px solid var(--line);border-radius:9px;background:var(--bg);padding:0 9px;font-size:13px;color:var(--ink)}
.remrow .btn{min-height:44px;padding:0 12px;font-size:13px}
.remchk{display:inline-flex;align-items:center;gap:7px;min-height:44px;padding:0 4px;font-size:12px;color:var(--ink-2);cursor:pointer}
.remchk input{width:24px;height:24px}
.remchip{display:inline-flex;align-items:center;gap:6px;background:var(--accent-soft);color:var(--accent);border-radius:999px;padding:6px 12px;font-size:12.5px;font-weight:600}
.remchip.sent{background:var(--st-done-bg);color:var(--st-done)}
.tfechip{display:inline-flex;align-items:center;gap:4px;font-size:10.5px;font-weight:700;color:var(--st-done);background:var(--st-done-bg);padding:2px 8px;border-radius:999px;white-space:nowrap}

/* мини-таймлайн карточки: полоса старт→срок + маркер конца, если начала нет */
.tl-span{position:absolute;top:-2px;height:8px;border-radius:5px;opacity:.85;z-index:1}
.tl-endmark{position:absolute;top:2px;width:11px;height:11px;transform:translate(-50%,-50%) rotate(45deg);border-radius:3px;z-index:2}
.tl-span.od,.tl-endmark.od{box-shadow:0 0 0 2px var(--alarm-line)}

/* ═══ ГОЛОС В КАРТОЧКЕ (Смена 2) ═══
   В покое блок не занимает НИ ОДНОГО пикселя: его просто нет в разметке, пока
   State.tcVoice пуст. Появляется над строкой ввода комментария — там, где
   человек уже говорит в карточку, и в зоне большого пальца. */
.tcv{background:var(--surface-2);border:1px solid var(--line);border-radius:14px;
  padding:12px;margin:0 0 10px;box-shadow:var(--sh-1)}
.tcv-h{display:flex;align-items:center;justify-content:space-between;gap:8px;
  font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink-2);margin-bottom:7px}
.tcv-fold{background:transparent;border:0;padding:2px 4px;font:inherit;text-transform:none;
  letter-spacing:0;color:var(--ink-2);cursor:pointer;min-height:24px}
/* свёрнутая строка-предложение: не разворачивает себя сама, только по тапу
   человека — и никогда не тянет прокрутку (владелец, 16.08) */
.tcv-collapsed{padding:0;overflow:hidden}
.tcv-collapsed-btn{display:block;width:100%;min-height:44px;padding:11px 14px;
  background:transparent;border:0;text-align:left;font-size:13px;line-height:1.35;
  color:var(--ink);cursor:pointer}
.tcv-collapsed-btn:active{background:var(--surface)}
.tcv-tr{background:var(--surface);border-radius:10px;padding:9px 11px;font-size:13.5px;
  line-height:1.45;color:var(--ink);margin-bottom:11px;word-break:break-word}
.tcv-tr .q{color:var(--ink-2)}
.tcv-rows{display:flex;flex-direction:column;gap:6px;margin-bottom:11px}
/* вся строка — одна цель нажатия 44 px: тап снимает правку (HAX G9) */
.tcv-row{display:flex;align-items:center;gap:9px;min-height:44px;width:100%;text-align:left;
  background:var(--surface);border:1px solid var(--line);border-radius:11px;padding:6px 10px;
  transition:opacity .18s,background .18s}
.tcv-row:active{transform:scale(.99)}
.tcv-row.off{opacity:.5}
.tcv-row.off .tcv-now{text-decoration:line-through}
.tcv-box{flex:none;width:22px;height:22px;border-radius:7px;border:2px solid var(--accent);
  display:grid;place-items:center;color:var(--on-accent);background:var(--accent);font-size:13px;line-height:1}
.tcv-row.off .tcv-box{background:transparent;border-color:var(--line);color:transparent}
.tcv-txt{min-width:0;flex:1}
.tcv-k{font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:var(--ink-2);display:block;line-height:1.3}
.tcv-v{font-size:13px;line-height:1.35;display:block;word-break:break-word}
.tcv-was{color:var(--ink-2)}
.tcv-now{font-weight:700}
.tcv-why{font-size:11px;color:var(--ink-2);display:block;line-height:1.3;margin-top:1px}
.tcv-row.low .tcv-now{font-weight:600;color:var(--ink-2)}
.tcv-act{display:flex;gap:8px;flex-wrap:wrap}
.tcv-act .btn{min-height:44px}
/* вопрос-дозаполнение: ровно ОДИН за раз (GOV.UK «одна вещь на страницу») */
.tcv-ask{margin-bottom:11px}
.tcv-ask .vsug{margin:0}
.tcv-more{margin-top:8px}
.tcv-more input{width:100%;height:44px;box-sizing:border-box;border:1px solid var(--line);
  border-radius:11px;background:var(--bg);color:var(--ink);padding:0 12px;font-size:14px}
.tcv-more-list{display:flex;flex-direction:column;gap:6px;margin-top:8px;max-height:238px;overflow-y:auto}
.tcv-grp{font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:var(--ink-2);margin:5px 0 1px}
.tcv-more-list .vchip{width:100%;justify-content:flex-start}
/* ═══ НАПОМИНАНИЕ НА ПЕРВОМ ЭКРАНЕ (Смена 2) ═══
   Стояло внутри свёрнутых «Деталей» на глубине 921 px — никто не долистывал,
   и на 251 задачу со сроком было ровно 0 напоминаний. Строка живёт ПОД полосой
   стадий: шапку, ужатую Сменой 1 до 120 px, не трогает вовсе. */
.tc3-rem{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:9px 0 0}
.tc3-rem .btn{min-height:44px;font-size:13px}
.tc3-rem .remchip{min-height:44px;padding:0 14px}
.tc3-rem-note{flex-basis:100%;font-size:11.5px;color:var(--ink-2);line-height:1.35}
.tc3-rem-note a{color:var(--accent);text-decoration:underline;cursor:pointer}
@media (max-width:430px){
  .vt{gap:11px;padding:11px}
  .vt-mic{width:58px;height:58px}
  .vt-mic svg{width:25px;height:25px}
  .vt-txt b{font-size:13.5px}
  .vchip{font-size:13px;padding:0 12px}
}

/* ═══════════════ ВОЛНА 5 — начинка карточки (ТЗ 7.2/7.3) ═══════════════
   «Сделана часть», Делает/Следит, помощники, передача, слияние, честная
   приёмка. Цвета только переменными (§1): бейдж части — заливка статуса
   «на проверке», третьего канала не выдумываем. */
/* бейдж «сделано 2 из 5»: ЕДИНЫЙ вид в шапке карточки и у счётчика шагов.
   Класс общий — строка доски (board.css) может взять его же слова и цвет. */
.partline{display:inline-flex;align-items:center;background:var(--st-review-bg);color:var(--st-review);
  border-radius:999px;padding:3px 10px;font-size:11px;font-weight:700;line-height:1.3;white-space:nowrap;
  font-variant-numeric:tabular-nums}
.tc3-what .partline{margin-top:6px}
/* счётчик шагов при частичной готовности — тот же вид; margin-left:auto
   наследуем от .subs-h .cnt, здесь только перекраска */
.subs-h .cnt.partline{color:var(--st-review)}
/* чипов стало три (Делает · Следит · Срок): на широком экране — один ряд,
   на телефоне остаются две колонки (третий чип честно переносится вниз) */
/* ── «В помощь» — соисполнители ── */
.helpers{margin-top:14px;border-top:1px solid var(--line);padding-top:2px}
.helpers .sect-lbl .cnt{margin-left:auto;font-weight:700;color:var(--ink-2);font-variant-numeric:tabular-nums}
.helpers-row{display:flex;flex-wrap:wrap;gap:7px;margin:0 0 9px}
.helper-chip{display:inline-flex;align-items:center;gap:7px;background:var(--surface-2);border-radius:11px;
  padding:0 0 0 7px;min-height:44px;max-width:100%;min-width:0}
.helper-chip .htx{min-width:0;display:flex;flex-direction:column;justify-content:center}
.helper-chip .hname{font-weight:600;font-size:13px;line-height:1.3}
.helper-chip .hnote{font-size:10.5px;color:var(--ink-2);line-height:1.3;max-width:180px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* крестик — полноценная тач-цель 44 (§3), а не мина 20 px */
.helper-chip .hx{flex:none;width:44px;height:44px;border-radius:10px;background:transparent;border:0;
  color:var(--ink-2);display:grid;place-items:center;cursor:pointer}
.helper-chip .hx:hover{background:var(--surface);color:var(--danger)}
.helper-chip .hx svg{width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:2.2;stroke-linecap:round}
.helpers .helpcall{min-height:44px}
.helpers .helpask{margin-top:2px}
/* поля листов Волны 5 — не мельче тач-нормы; фон полей как у прочих листов */
.tc3-sheet select.ie-input,.tc3-sheet input.ie-input{min-height:44px;background:var(--surface)}
/* строчное действие (§2): текст цветом акцента, без рамки и заливки */
.tc3-undo{align-self:flex-start;min-height:44px;padding:0 4px;background:none;border:0;color:var(--accent);
  font:inherit;font-size:13px;font-weight:600;cursor:pointer;text-decoration:underline;text-underline-offset:3px}
.tc3-undo:hover{color:var(--accent-hover)}
/* честная приёмка: лист «Осталось N шагов». Терракоту не трогаем — это не
   просрочка; янтарь «на проверке» и есть его канал. */
.forcebox{border-left:3px solid var(--st-review)}
.force-list{margin:0;padding:0 0 0 18px;display:flex;flex-direction:column;gap:4px;
  font-size:13px;line-height:1.4;color:var(--ink)}
.force-list li::marker{color:var(--st-review)}
/* слияние дублей: строки поиска */
.merge-list{display:flex;flex-direction:column;gap:6px;max-height:238px;overflow-y:auto}
.merge-row{display:flex;align-items:center;gap:9px;min-height:44px;text-align:left;border:1px solid var(--line);
  border-radius:10px;background:var(--surface);padding:6px 11px;font:inherit;color:var(--ink);cursor:pointer;min-width:0}
.merge-row:hover{border-color:var(--accent);background:var(--accent-soft)}
.merge-row b{flex:none;font-size:12.5px;color:var(--accent)}
.merge-row .mt{flex:1;min-width:0;font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.merge-row .ms{flex:none;font-size:10.5px;font-weight:700;color:var(--ink-2)}
.merge-warn{font-size:13px;line-height:1.45;background:var(--surface);border-radius:10px;padding:10px 12px;color:var(--ink)}

/* ══════════ ПОДБОРЩИК «@» В ПОЛЕ РЕПЛИКИ ══════════
   Владелец 14 августа: «хочу тегать любого сотрудника». Список висит НАД полем
   ввода (bottom:100%): низ экрана на телефоне занимает клавиатура, и открывшись
   вниз он оказался бы под ней. Зона нужна ровно для этой привязки. */
.tc-cmt-zone{position:relative}
.upom-box{position:absolute;left:0;right:0;bottom:calc(100% + 6px);z-index:2;
  background:var(--card);border:1px solid var(--line);border-radius:12px;
  box-shadow:var(--sh-2);padding:4px;max-height:282px;overflow-y:auto;
  display:flex;flex-direction:column;gap:2px}
.upom-box[hidden]{display:none}
/* строка списка — тач-цель 44 px (§3): по подборщику попадают пальцем на стройке.
   Выделение строки — заливкой И рамкой, не одной краской (WCAG 1.4.1). */
/* ⚠️ flex:none — НЕ УКРАШЕНИЕ. Список это колонка-флекс с потолком высоты, и без
   запрета на сжатие шестая строка ужималась до 28 px: замер сторожа показал
   тач-цель 923×28 при норме 44. Теперь строки держат высоту, а лишние уходят
   под прокрутку — палец попадает по любой. */
.upom-r{flex:none;display:flex;align-items:center;gap:8px;min-height:44px;width:100%;text-align:left;
  border:1px solid transparent;border-radius:9px;background:none;padding:4px 10px;
  font:inherit;color:var(--ink);cursor:pointer;min-width:0}
.upom-r:hover{background:var(--accent-ghost)}
.upom-r.on{background:var(--accent-soft);border-color:var(--accent)}
.upom-r .nm{flex:1;min-width:0;font-size:13.5px;font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* ник — служебный: мелким и никогда не вместо имени (правило имени по системе) */
.upom-r .un{flex:none;font-size:11px;color:var(--ink-3)}
.upom-pusto{font-size:12.5px;color:var(--ink-2);padding:11px 10px}
/* упоминание в готовой реплике: обращение к человеку видно, но это не ссылка —
   нажимать там нечего, поэтому вес и цвет акцента без подчёркивания */
.cmt-at{font-weight:700;color:var(--accent)}

/* ═══════════════ P0 v4 — КАРТОЧКА КАК СТАБИЛЬНОЕ РАБОЧЕЕ ОКНО ═══════════════
   Задача P0: карточка не растёт от содержимого. Шапка (.tc4-head) — компактная
   зона фиксированного роста; длинное (чат, шаги, документы, помощники) живёт в
   колонках .tc-grid, и каждая прокручивается сама. Цвета — только var(--…). */

/* ── шапка: низ отчёркнут, ниже — только прокручиваемые области ── */
/* 10 → 6/9: шапка ужалась до одной строки, и прежние отступы вокруг неё стали
   заметной долей высоты. Замер: .tc3-top 44 + .tc4-head 55 = 99 px обвязки
   против 187 до правки — остальное ушло ленте сообщений. */
.tc4-head{border-bottom:1px solid var(--line);padding-bottom:4px;margin-bottom:6px}
/* ⚠️ 6/9 → 4/6 — ЭТО ПЛАТА ЗА СТРОКУ АДРЕСА, А НЕ КОСМЕТИКА. Адрес встал
   собственной строкой в 30 px над названием и виден теперь на всех ширинах;
   5 px из этих тридцати возвращает сжатие обвязки здесь, ещё 4 — отступы
   .tc4-line и .tc4-dlina ниже. Чистая цена названа числом в отчёте. */
/* номер карточки: справочный текст, не цель нажатия — владелец зовёт карточки
   по имени, но номер нужен для «Слить с…» и разговоров с машиной */
.tc4-num{flex:none;align-self:flex-start;margin-top:8px;font-size:11px;font-weight:700;
  color:var(--ink-2);font-variant-numeric:tabular-nums;white-space:nowrap}

/* ── ОДНА СТРОКА ШАПКИ: делает · следит · срок · стадия · напоминание ──
   Было две полосы: .tc3-chips (сетка чипов, 57 px) и .tc4-staterow (степпер из
   четырёх кнопок, 52 px) = 109 px над лентой в 87 px. Владелец 31.08: «это
   важная информация, но её можно уместить в одну строку вместе со статусом».
   Чипы людей и срока тянутся (flex:1) и обрезаются многоточием, как и раньше;
   стадия и напоминание — цели фиксированной ширины в хвосте строки.
   position:relative ОСТАВЛЕН страховкой на случай попапа без своего якоря, но
   попап стадии с 02.09 якорится к САМОМУ ЧИПУ (.tc4-st ниже): от строки он
   уезжал на 1018 px вправо, потому что чип стоит третьим слева, а правило было
   писано, когда он стоял четвёртым, у самого края. */
.tc4-line{display:flex;gap:7px;margin:2px 0 0;align-items:center;flex-wrap:wrap;position:relative}
.tc4-line>*{min-width:0}
.tc4-line .tc3-chip{flex:1 1 150px}
.tc4-line .tc4-st{flex:none}
.tc4-line-hv{display:flex;gap:7px;align-items:center;flex-wrap:wrap;min-width:0}
.tc4-line-hv:empty{display:none}
/* ТЕЛЕФОН: строка становится сеткой 2×2 — «делает | следит» и «срок | стадия».
   Было три полосы (два этажа чипов по 57 px плюс полоса стадий 52), стало две
   по 44. Ячейка «стадия» держит и напоминание, когда оно есть (на проверке его
   нет вовсе); не влезли в ячейку — переносятся внутри неё, а не отдельной
   полосой на всю ширину. */
/* ═══ ТЕЛЕФОН: СТРОКА «ДЕЛО» — ОДНА ПОЛОСА В 44 px ═════════════════════════
   Было: сетка 2×2 из четырёх чипов плюс стадия — 152 px шапки на 375. Стало:
   чип действия, стадия и срок в одну строку; «делает» и «следит» на этой
   ширине живут в СВОЙСТВАХ панели (в 305 px пять чипов не помещаются, а ленте
   по §6.2 нужна половина окна).
   ЛЕСТНИЦА СБРОСА НАПИСАНА ЗАРАНЕЕ, ступень первая: у чипа срока гаснет слово
   подписи — дата сама говорит, что она срок. Просрочка и «сегодня» слово
   сохраняют: там оно и есть сигнал (§1, терракота — канал срока).
   Ступень вторая — перенос: строка честно уходит на второй этаж вместо того,
   чтобы резать многоточием индонезийское «Perlu diperiksa» (15 знаков против
   6 у «Proses»). Обрезанное название стадии хуже второй строки. */
@container kartochka (max-width:600px){
  /* nowrap — не украшение: перенос стоит 50 px ленты, и на 617 доля чата падала
     с 50,3 % до 41,7 %, ниже порога §6.2. Полоса обязана быть ровно одна. */
  .tc4-line{display:flex;flex-wrap:nowrap;gap:5px;align-items:center}
  .tc4-line>*{width:auto;min-width:0}
  /* ступень 1: чип действия ужимается полями, слово остаётся целым */
  .tc4-line .tc4-do{padding:0 10px}
  /* ступень 2: у чипа стадии гаснет значок — статусную заливку и без него несёт
     полоса .tc3-bar в строке названия (§1: заливка = статус, один канал) */
  .tc4-line .tc4-st{flex:1 1 auto;min-width:0}
  .tc4-line .tc4-line-hv{flex:1 1 auto;min-width:0}
  .tc4-line .tc4-st>summary{padding:0 8px;gap:5px;min-width:0}
  .tc4-line .tc4-st>summary .stg-ic{display:none}
  /* ступень 3: карточка возвращена — в чипе остаётся ОДНО слово «Вернули».
     «В работе» + «Вернули» в 305 px не входят ни на одном языке, а из двух
     важнее то, что новое; полное состояние остаётся в подсказке чипа. */
  .tc4-line .tc4-st-sum.vz .nm{display:none}
  /* ступень 4, последняя: длинное имя стадии («Perlu diperiksa» — 15 знаков
     против 6 у «Proses») режется многоточием, а не уносит строку на второй
     этаж. Слово целиком остаётся в title и aria-label. */
  .tc4-line .tc4-st>summary .nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
  /* ═══ СТУПЕНЬ 1 ЛЕСТНИЦЫ СБРОСА — ДОВЕДЕНА ДО КОНЦА ══════════════════════
     Было: слово подписи гасло у `:not(.od):not(.td)`, то есть ровно там, где
     места и так хватало, а у просроченной оставалось «ПРОСРОЧЕНО/TERLAMBAT» в
     коробке 132 px. Замер приёмки: поле даты просило 155 px, правый край поля
     357 при правом крае строки 340 — на 375 у карточки 617 дата читалась как
     «30.08.202», оба языка, обе темы. И вся строка переполнялась:
     scrollWidth 312 при clientWidth 305.
     План писал ступень 1 буквально: «чип срока теряет слово ПРОСРОЧЕНО, дата
     сама говорит, что она срок; просрочка говорит терракотовой обводкой и
     знаком +4 в имени — канал §1, а не второе слово». Слово гаснет у ВСЕХ.
     Каналы срока при этом целы оба: заливка чипа --alarm-bg у просроченной
     (.tc3-chip.due.od выше) и знак «+N» / «!» терракотой в строке имени
     (.tc3-urg, tcUrgDot). Дата — данные, а не сигнал, и она перестала резаться. */
  .tc4-line .tc3-chip.due{flex:0 0 88px}
  .tc4-line .tc3-chip.due .lbl{display:none}
}
/* ⚠️ Подписи «ДЕЛАЕТ» и «СЛЕДИТ» — В СТРОКУ слева, а не этажом над выпадашкой.
   Ровно тот же приём, которым уже вылечен чип срока девятью сотнями строк выше
   (.tc3-chip.due): этажом ряд давал 57 px, строкой встаёт в тач-норму 44.
   Слово остаётся видимым — владелец назвал «кто делает и кто следит» важным,
   прятать его в подсказку было бы потерей, а места в строке 1354 px хватает. */
  /* Чип с началом («05.08 → 28.08») на узком экране берёт ВСЮ строку: два поля
     по 44 px в 88 px не живут, а второй этаж внутри чипа владелец отверг 03.09. */
  .tc4-line .tc3-chip.due.s-nach{flex:1 1 100%}
  /* Обе даты — коротким текстом, родное поле поверх прозрачным (замер 375:
     поле в 70 px печатало «28.08.202», чип с началом наезжал на «В работе»). */
  .tc4-line .tc3-chip.due .due-wrap .due-txt{display:inline;white-space:nowrap;padding:0 6px}
  .tc4-line .tc3-chip.due .due-wrap input[type=date]{position:absolute;inset:0;width:100%;min-width:0;height:100%;
    flex:none;margin:0;padding:0;border:0;opacity:0;cursor:pointer}
  /* Чип с началом («05.08 → 28.08») в 88 px не живёт: строка переносится, и
     чип встаёт своей строкой во всю ширину — под людьми, а не поверх них. */
  .tc4-line:has(.tc3-chip.due.s-nach){flex-wrap:wrap}
.tc4-line .tc3-chip>span:last-child{display:flex;align-items:center;gap:6px;align-self:stretch}
/* Обёртка срока: текст + поле; на широкой карточке текст скрыт, поле обычное. */
.tc3-chip.due .due-wrap{position:relative;display:flex;flex:1 1 70px;min-width:0;align-items:center;height:44px}
.tc3-chip.due .due-wrap .due-txt{display:none}
.tc3-chip.due .due-wrap:focus-within{outline:2px solid var(--accent);outline-offset:-2px;border-radius:8px}
/* ═══ § НАЧАЛО ВНУТРИ ЧИПА СРОКА (владелец 03.09: «в строке достаточно места») ═
   Поле начала — тот же орган, что у срока (44 px), уже по ширине; стрелка —
   данные, не орган. Никакой второй строки: начало, стрелка, срок — один ряд. */
/* Начало — короткий текст, а родное поле даты лежит поверх него прозрачным
   (замер судьи 03.09: input[type=date] просит 129 px, второй такой в чипе на
   390 резал обе даты). Специфичность выше, чем у `.tc3-chip.due input[type=date]`. */
.tc3-chip.due .nach-wrap{position:relative;flex:none;display:inline-flex;align-items:center;height:44px;min-width:44px;padding:0 2px 0 4px}
.tc3-chip.due .nach-wrap input[type=date]{position:absolute;inset:0;width:100%;min-width:0;height:100%;flex:none;
  margin:0;padding:0;border:0;opacity:0;cursor:pointer}
.tc3-chip.due .nach-wrap:focus-within{outline:2px solid var(--accent);outline-offset:-2px;border-radius:8px}
.tc3-chip.due .nach-txt{flex:none;white-space:nowrap}
.tc3-chip.due .strelka{flex:none;padding:0 3px;color:var(--ink-2);font-size:12px;line-height:1}
.tc4-line .tc3-chip .lbl{flex:none;line-height:1.2}
/* ⚠️ У ВЫПАДАШКИ ПОЛ 44, У НАДПИСИ — 0. min-width:0 стоял на обеих, и по-инде‐
   зийски выпадашки «Делает»/«Следит» сжимались до 30.7 и 43.4 px по ширине при
   росте 44 (замер 03.09, 853×533, карточка 620, ID) — недобор по §3 и 2.5.5.
   Пол в 44 px горизонтали не даёт: ряд чипов на 853 шире восьмисот. */
.tc4-line .tc3-chip .val{min-width:0}
.tc4-line .tc3-chip .tc3-asg{min-width:44px}
.tc4-line .tc3-chip .nick{flex:none}

/* ── СТАДИЯ ЧИПОМ, ВЫБОР — В ПОПАПЕ ──
   Полоса из четырёх кнопок по 335 px свернулась в одну цель 44 px. Сменить
   статус по-прежнему можно: попап открывает те же четыре кнопки .cyc-s с теми
   же App.cycTap и moveDenyReason. Приём — ровно тот, что уже живёт у чипа
   напоминания рядом (details + .tc4-rem-pop), второго паттерна не заведено. */
.tc4-st>summary{list-style:none;cursor:pointer;display:inline-flex;align-items:center;gap:7px;
  min-height:44px;min-width:44px;padding:0 10px;border-radius:11px;background:var(--surface-2);
  font-size:12px;font-weight:700;color:var(--ink-2)}
.tc4-st>summary::-webkit-details-marker{display:none}
.tc4-st>summary:hover{background:var(--accent-soft);color:var(--accent)}
.tc4-st[open]>summary{background:var(--accent-soft);color:var(--accent)}
.tc4-st>summary:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
/* значок стадии красит ЗАЛИВКА статуса (§1: заливка = статус), слово рядом —
   цветом той же стадии; белого по янтарю не делаем, контраст ниже нормы */
.tc4-st>summary .stg-ic{flex:none;width:28px;height:28px;border-radius:9px;display:grid;place-items:center;
  background:var(--cyc-b,var(--surface));color:var(--cyc-c,var(--ink-2))}
.tc4-st>summary .stg-ic svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}
.tc4-st>summary .nm{color:var(--cyc-c,var(--ink));white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tc4-st>summary>svg{width:14px;height:14px;flex:none;stroke:currentColor;fill:none;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}
/* ── ЧИП СТАДИИ БЕЗ ХОДА: ТОТ ЖЕ ВИД, НО НЕ ЦЕЛЬ НАЖАТИЯ ──
   Зритель («Только просмотр») стадию не двигает, и попапа у него нет: молчащей
   кнопки не рисуем (§7). Вид один в один, чтобы состояние читалось одинаково у
   всех ролей (§4.6 п.4 — роль меняет содержимое ячейки, а не её место и вид). */
.tc4-st>.tc4-st-sum{display:inline-flex;align-items:center;gap:7px;min-height:44px;min-width:44px;
  padding:0 10px;border-radius:11px;background:var(--surface-2);font-size:12px;font-weight:700;
  color:var(--ink-2);cursor:default}
.tc4-st>.tc4-st-sum .stg-ic{flex:none;width:28px;height:28px;border-radius:9px;display:grid;
  place-items:center;background:var(--cyc-b,var(--surface));color:var(--cyc-c,var(--ink-2))}
.tc4-st>.tc4-st-sum .stg-ic svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}
.tc4-st>.tc4-st-sum .nm{color:var(--cyc-c,var(--ink));white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
@container kartochka (max-width:600px){
  .task-inline .tc4-line .tc4-st>.tc4-st-sum{padding:0 8px;gap:5px;min-width:0}
  .task-inline .tc4-line .tc4-st>.tc4-st-sum .stg-ic{display:none}
  .task-inline .tc4-line .tc4-st>.tc4-st-sum .nm{min-width:0}
}
/* в попапе места хватает — стадии встают столбиком, и под каждой возвращается
   факт «кто · когда», который в компактной полосе жил только в title */
.tc4-st-pop .cyc.v4{flex-direction:column;gap:2px;background:none;padding:0;overflow:visible}
.tc4-st-pop .cyc.v4 .cyc-s{flex:none;width:100%;align-items:flex-start;flex-direction:row;padding:6px 8px}
.tc4-st-pop .cyc.v4 .cyc-s .nm{font-size:13px;font-weight:600}
.tc4-st-pop .cyc.v4 .cyc-s .fact{display:block;flex:1;text-align:right;font-size:10.5px;color:var(--ink-2)}
.tc4-st-pop .cyc-note{margin:6px 2px 0}


/* ── компактный степпер цикла (P0-3): значок + слово + цвет, одна строка.
   min-height:44 наследуется от базового .cyc-s — тач-норма живёт. ── */
.cyc.v4{flex:1 1 260px;margin:0;padding:4px;gap:2px;border-radius:11px}
.cyc.v4 .cyc-s{flex-direction:row;align-items:center;gap:7px;min-width:0;padding:4px 7px;justify-content:flex-start}
.cyc.v4 .cyc-s .rail,.cyc.v4 .cyc-s .fact{display:none}
.cyc.v4 .stg-ic{flex:none;width:28px;height:28px;border-radius:9px;display:grid;place-items:center;
  background:var(--surface);color:var(--ink-2)}
/* ⚠️ размер svg задан и здесь, и в атрибутах ico — страховка от «клякс» */
.cyc.v4 .stg-ic svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}
/* текущая стадия: заливка -bg пары статуса + значок цветом статуса (§1: заливка
   = статус; белого по янтарю не делаем — контраст ниже нормы) */
.cyc.v4 .cyc-s.cur .stg-ic{background:var(--cyc-b,var(--accent-soft));color:var(--cyc-c,var(--accent))}
.cyc.v4 .cyc-s.past .stg-ic{background:var(--st-done-bg);color:var(--st-done)}
/* overflow-wrap:anywhere — страховка узких промежуточных ширин (560–900px):
   «Подтверждено»/«Dikonfirmasi» одним словом шире отведённого и без переноса
   вылезали бы на соседа — это наложение, брак по сторожу §10 */
.cyc.v4 .cyc-s .nm{font-size:11px;line-height:1.25;min-width:0;overflow-wrap:anywhere}
.cyc.v4 .cyc-s.cur .nm{color:var(--cyc-c,var(--accent))}
/* УЗКИЙ ЭКРАН: слово — только у текущей стадии, остальные — значок с цветом
   (смысл в title и в «Вся история»). Арифметика 390px: контент строки ≈322px,
   в четыре подписи по ~33px «Подтверждено» (≈72px) не влезало — регресс
   дефекта «Подтверждено за краем» (см. правило 759px выше). Теперь три
   значковые кнопки ≈ 3×44 + просветы = 136px, текущей остаётся ≈180px —
   слово входит целиком на обоих языках, бокового скролла нет. */
@container kartochka (max-width:520px){
  .cyc.v4 .cyc-s{flex:0 1 auto;min-width:44px;justify-content:center;padding:4px 5px}
  .cyc.v4 .cyc-s:not(.cur) .nm{display:none}
  .cyc.v4 .cyc-s.cur{flex:1 1 auto;justify-content:flex-start}
  /* ⚠️ ПОПАП СТАДИЙ — ИСКЛЮЧЕНИЕ. Правило выше писано для ГОРИЗОНТАЛЬНОЙ полосы,
     где четыре подписи не влезали в 322px. В попапе стадии стоят столбиком во
     всю ширину 260–340px, места хватает — а без этой строки на телефоне у трёх
     стадий из четырёх нет названия, и смена статуса становится выбором из
     безымянных значков (§5: каждая надпись парой RU/ID, §7: молчащая кнопка —
     брак). Специфичность равная (0,5,0), решает порядок — правило ниже. */
  .tc4-st-pop .cyc.v4 .cyc-s{flex:none;width:100%;justify-content:flex-start;padding:6px 8px}
  .tc4-st-pop .cyc.v4 .cyc-s .nm{display:block}
}

/* ── НАПОМИНАНИЕ В СВОЙСТВАХ: СТРОКА, А НЕ ЧИП С ПОПАПОМ ──
   Чип .tc4-rem и его попап сняты вместе с правилами: попап якорился к строке
   «Дело» (position:relative), а из СВОЙСТВ ближайшим позиционированным предком
   стала .kp-box — попап вставал ниже нижнего края панели и срезался клипом
   карточки. Наружу это читалось как «чип ничего не открывает», и вместе с
   попапом были недостижимы быстрое «завтра в 9:00», «Снять», счёт точек
   лестницы и выключатель авто. Правило: в панели третьего уровня раскрытия не
   бывает — органы стоят открытыми (card.napominaniya.vid.js, tcRemindRow). */
.tc3-rem.rem-in{margin:0}
.tc3-rem.rem-in .au{flex:none;font-size:9.5px;font-weight:700;text-transform:uppercase;
  letter-spacing:.04em;color:var(--accent);background:var(--accent-soft);
  border-radius:999px;padding:3px 8px}
.rem-net{color:var(--ink-2);font-weight:600}
/* якорь — .tc4-line{position:relative}: right:0 — правый край СТРОКИ (он же
   край содержимого карточки), панель никогда не пересекает clip-границу;
   min-width ужат до ширины строки на самых узких экранах */
/* ⚠️ второй класс `tc4-popup` на этих панелях — НЕ оформление, у него нет и не
   должно быть правил. Это имя, по которому сторож вёрстки узнаёт накладную
   панель (tests/verstka_storozh.js:397, OVERLAY_RE) и перестаёт сравнивать её с
   тем, что она СОБОЙ ЗАКРЫВАЕТ: панель непрозрачная и лежит выше (z-index:8),
   а без имени сторож считал её обычным блоком в потоке и на открытом попапе
   давал шесть ложных «наложений» на 375. Правило конвенции — в самом стороже:
   «Абсолютная панель, названная накладной». */
/* ⚠️ ПОПАП В СТРОКЕ «ДЕЛО» ОСТАЛСЯ ОДИН — у чипа стадии. Второй (напоминание)
   снят: он уехал в СВОЙСТВА, где абсолютная коробка от этого якоря считается
   уже не отсюда и срезается. Заведёте в строке второй попап с такой же
   коробкой — обяжите оба <details> общим name (TC4_SHAPKA_GRP, card.vid.js):
   иначе открытыми вдвоём они лягут друг на друга, и никакое правило отсюда
   не спасёт. */
/* ⚠️ ЯКОРЬ ПЕРЕЕХАЛ СО СТРОКИ НА САМ ЧИП (02.09) — ЭТО ГЛАВНАЯ ПОЧИНКА ЖАЛОБЫ
   «ЕСЛИ МЕНЮ ВЫПАДАЮЩЕЕ — ОНО ДОЛЖНО ВЫПАДАТЬ». Стояло right:0 от .tc4-line
   шириной 1354, а чип стадии с прошлого прохода стоит ТРЕТЬИМ СЛЕВА: замер
   02.09 на 1440 — чип 115…242, попап 1133…1393, левые края разъехались на
   +1018 px, между правым краем чипа и попапом 891 px пустоты. Наружу это и есть
   «надо открывается в жопе»: единственный ход обратно в «Надо» лежит в этом
   попапе, а он вылезал в правом нижнем углу карточки.
   Правило right:0 не менялось ни разу — переехал чип. Поэтому якорь теперь
   собственный (.tc4-st{position:relative}), а от правого края уводит подводка
   tcPopapVVidu: сначала попытка встать под чипом слева, потом сдвиг внутрь
   карточки (приём flip-then-shift, Floating UI). Ширину задаёт сам попап, а не
   доля от чипа: min(260px,100%) от чипа в 127 px давало бы 127. */
.tc4-st{position:relative}
.tc4-st .tc4-rem-pop{position:absolute;left:0;right:auto;top:calc(100% + 6px);z-index:8;
  min-width:min(260px,90cqw);max-width:min(340px,96cqw);
  background:var(--surface);border:1px solid var(--line);border-radius:12px;box-shadow:var(--sh-3);
  padding:11px;animation:tcPickIn .16s var(--ease)}

/* ── помощники свёрнуты (P0-6): аватары внахлёст + «+N», вся строка — одна
   цель нажатия ≥44, раскрывает лист с полным списком и добавлением ── */
.helpers-mini{display:inline-flex;align-items:center;gap:7px;min-height:44px;padding:6px 12px 6px 8px;
  border-radius:11px;background:var(--surface-2);border:0;cursor:pointer;color:var(--ink-2);max-width:100%}
.helpers-mini:hover{background:var(--accent-soft);color:var(--accent)}
.helpers-mini .avatar{margin-left:-8px;box-shadow:0 0 0 2px var(--surface-2)}
.helpers-mini .avatar:first-of-type{margin-left:0}
.helpers-mini svg{width:15px;height:15px;flex:none;stroke:currentColor;fill:none;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
.avatar.more{background:var(--surface);border:1.5px solid var(--line);color:var(--ink-2);
  font-size:10px;padding:0}

/* ── шаги: своя прокрутка (~9 строк по 44) — 50 шагов не растягивают карточку ──
   ⚠️ БЕЗ overscroll-behavior:contain (снят 01.09). Потолок у списка есть, своя
   прокрутка есть — но список стоит ВНУТРИ СТРАНИЦЫ, а не во всплывающем окне:
   докрутил шаги до последнего — страница обязана поехать дальше тем же
   движением. contain оправдан только там, где под прокруткой лежит чужой
   экран (шторка, модалка). ── */
.subs .subs-list{max-height:404px;overflow-y:auto}

/* ── документы карточки: свои строки в ограниченной области со своей прокруткой.
   contain снят 01.09 по той же причине, что у шагов: это часть страницы. ── */
#docBlockTC .doclist{max-height:352px;overflow-y:auto}

/* ── крошка «Где» (P0-4): одна строка с многоточием; полное значение — в title
   ячейки и в раскрытом списке карандаша. overflow здесь НЕ режем: панель .pm
   якорится к этой же строке и обрезалась бы вместе с длинным словом. ── */
.task-inline .tc3-crumb{flex-wrap:nowrap}
.task-inline .tc3-crumb .tc3-cell{flex:1 1 auto;min-width:34px}
.task-inline .tc3-crumb .sep{flex:none}
.task-inline .tc3-crumb .tc3-val{max-width:none;flex:1 1 auto}
.task-inline .tc3-crumb .tc3-pick{flex:none}

/* обёртка карточки не должна быть портом прокрутки: прокручиваются только
   области внутри (колонки, лента, шаги, документы) */
.task-inline .db{overflow:clip}

/* ═══════════════ ОКНО КАРТОЧКИ — КАРТОЧКА НЕ РАСТЁТ ОТ ЧАТА ═══════════════
   Слово владельца 01.09 (дословно): «чтобы у нас был комфортный размер окна для
   карточки. То есть размер чата — чтобы он прокручивался и карточка не росла от
   чата». Этим ОТМЕНЕНО решение 31.08 «пускай карточка растёт», и запрет
   «ставить сюда height/max-height обратно — брак», стоявший на этом месте,
   снят вместе с ним. Второй такой же запрет — у .tc-comments-list выше — тоже
   переписан в этой правке: два взаимоисключающих закона в одном файле читающий
   видеть не должен.

   ПОЧЕМУ НЕ ПОВТОРИТСЯ ПРОВАЛ 31.08 («окно есть, чату 87 px»). Тогда окно
   поставили, не убрав из закреплённой обвязки ничего. Замер 01.09 на карточке
   «DED Arsitektur Swimming Pool» (28 реплик): закреплено было название 70–104,
   строка шапки 51–152, подвал .df 69 (на 375 — 177), композер 62, и в одной
   колонке с лентой стояли причина возврата 79–118, главное действие 52–106 и
   «Вся история» 46. Теперь закреплено ровно три вещи: название, строка шапки и
   композер. Подвал .df, «Вся история» и весь контекст переехали в колонку
   справа и листаются вместе с ней (card.vid.js, taskCardHtml).

   ДВЕ РАЗВИЛКИ, И ОНИ НЕЗАВИСИМЫ — у каждой своё число:
   1. СКОЛЬКО КОЛОНОК — по ширине САМОЙ КАРТОЧКИ (@container kartochka, порог 760,
      обоснование у сетки .tc-grid.v3 выше). Окно при этом включается на ВСЕХ
      ширинах: правило .task-inline ниже стоит без единого условия.
   2. ЧТО ЗАКРЕПЛЕНО — по ВЫСОТЕ ОКНА (@media min-height). Две самостоятельно
      прокручиваемые колонки с закреплённой шапкой стоят 254 px постоянной
      обвязки: название 70, шапка 55, полоса ответа 65, поля 12 и липкое главное
      действие 70. Чтобы ленте досталась половина окна, нужно H − 272 ≥ 0,5·H,
      то есть окно ≥544 px и экран ≥769. Берём 800 с запасом — замер на 1280×800
      даёт ровно 52,8 %. Ниже — один порт: шапка и действие едут вместе с
      содержимым, лента забирает порт целиком (замер 1024×768: два порта дают
      271 px = 49,9 %, один порт — 396 px = 73 %).
      Замер 853×533: две колонки с закреплённой шапкой оставили бы ленте 54 px
      (0,4 реплики, 18 % окна) — это тот же провал 31.08 другими цифрами; один
      порт даёт 164 px (1,4 реплики, 53 % окна). Колонок при этом всё равно две:
      число колонок решает ширина, а не высота. */

/* ── САМА КАРТОЧКА: окно с потолком, но БЕЗ height ──
   max-height, а не height: короткая задача остаётся короткой, пустого окна под
   двумя репликами не возникает. container-type даёт развилку колонок и делает
   .task-inline контейнером запросов по имени kartochka. */
/* position:relative — ЯКОРЬ ПАНЕЛИ «ПОДРОБНО». container-type:inline-size уже
   включает contain:layout и сам делает карточку содержащим блоком для
   абсолютных потомков, но в колонке канбана контейнер выключен
   (.col .task-inline{container-type:normal} внизу файла) — там панель уехала бы
   к ближайшему позиционированному предку. Одна строка закрывает оба случая. */
.task-inline{display:flex;flex-direction:column;max-height:var(--kartochka-okno);
  position:relative;container-type:inline-size;container-name:kartochka}
/* ⚠️ ВЕРТИКАЛЬНЫЕ ПОЛЯ КАРТОЧКИ УРЕЗАНЫ 18/18 → 10/0. Это не косметика: полоса
   ответа выросла на два этажа ради прямого требования владельца («строка
   написания текста — во всю длину карточки»), и 26 px полей — самое дешёвое,
   чем за это платить. Полоса ответа и так отбита сверху своей линией и стоит
   вплотную к низу окна, а название сверху отбито собственным ростом 44.
   Ленте эти 26 px идут целиком: на 375 это разница между 2,85 и 3,07 реплики,
   то есть между непройденным и пройденным порогом §6.2. */
.task-inline .db{flex:1 1 auto;min-height:0;display:flex;flex-direction:column;padding:10px 18px 0}
/* ТЕЛЕФОН: верхнее поле 10 → 6. Четыре пикселя — часть платы за строку адреса:
   на 375 они идут ленте целиком, а сверху карточку и без них отбивает
   собственный рост строки адреса. */
@container kartochka (max-width:600px){ .task-inline .db{padding-top:6px} }
/* название и строка шапки не растут и не сжимаются — это закреплённая обвязка */
.task-inline .tc3-top{flex:none}
.task-inline .tc4-head{flex:none}

/* ── ПОРТ: всё между названием и композером ──
   По умолчанию (узкая карточка ИЛИ низкий экран) порт один и прокручивается
   сам: шапка, действие, лента и контекст едут вместе. Своей прокрутки у ленты
   тут нет — и не нужно: карточка от длины переписки всё равно не растёт,
   потолок держит окно. Второй режим — ниже, в @media(min-height:740px). */
.task-inline .tc-port{flex:1 1 auto;min-height:0;overflow-y:auto}
/* ⚠️ overscroll-behavior У ПОРТА НЕ ПОЯВЛЯЕТСЯ. Владелец 01.09: «дочитал чат до
   конца — страница дальше не листается». Порт стоит ВНУТРИ страницы, а не
   всплывающим окном поверх чужого экрана: кончилось прокручиваемое внутри —
   тем же движением едет страница. Правило §8 стиля. */
/* правило ≥901 из блока сетки v2 давало правой колонке собственную прокрутку
   всегда; в режиме одного порта это лишняя вложенность — снимаем адресно */
.task-inline .tc-port .tc-col-right{min-height:auto;overflow:visible}
.task-inline .tc-port .tc-col-left{min-height:auto;overflow:visible}
/* набор в режиме одного порта — обычный блок под лентой, своей прокрутки не
   заводит: третий уровень прокрутки запрещён (страница → порт, и всё) */
.task-inline .tc-port .tc-col-nabor{min-height:auto;overflow:visible}
/* ⚠️ И СПИСОК ШАГОВ В НЁМ — ТОЖЕ БЕЗ СВОЕЙ ПРОКРУТКИ. Потолок 404 у .subs-list
   писался для бесконечной колонки контекста; под лентой внутри порта он дал бы
   третий уровень прокрутки (страница → порт → список), а третьего не бывает.
   Набор течёт целиком, расстояние до него — один свайп вниз. */
.task-inline .tc-port .tc-col-nabor .subs-list{max-height:none;overflow:visible}

/* ── КОМПОЗЕР: настоящая нижняя полоса окна ──
   Был липким блоком внутри колонки и ложился ПОВЕРХ листа сдачи: замер 01.09 —
   перекрытие 774×62 на 853 и 305×62 на 375, elementFromPoint в центре двух
   галок этапов возвращал textarea композера, то есть нажать их было нельзя.
   Полоса под портом наехать не может по устройству: она не в потоке порта.
   ⚠️ ПОЛОСУ ВНУТРЬ СЕТКИ НЕ ВНОСИТЬ. Узел .tc-cmt-sticky лежит ПОСЛЕ
   </div><!-- /.tc-port -->, и это оплачено 01.09. Внесёшь второй строкой
   сетки — на узких она уедет со скроллом порта и снова ляжет на лист сдачи.

   ── 02.09: ПОЛОСА ШИРИНОЙ РОВНО С ЛЕНТУ ────────────────────────────────────
   Владелец: «Строка ввода под всей карточкой — так не должно быть, она должна
   быть ровно ширины самого окна чата». Замер до правки: 1390 при ленте 1010 на
   1440 (362 px под панелью набора) и 341 при 296 на 375/853/1024.
   Лечится НЕ переносом узла, а колоночной геометрией внутри самой полосы:
   полоса получает ту же сетку, что .tc-grid.v3 (1fr · 24 · 320), содержимое
   живёт в первой колонке, вторая пустует. Отрицательные поля −18/−18 сняты:
   они нарочно выводили полосу за поля карточки, и ровно они давали 36 из 45 px
   расхождения на узких. Оставшиеся 9 — полоса прокрутки порта (base.css,
   ::-webkit-scrollbar{width:9px}); её компенсирует margin-right у .tc-cmt-kol,
   а scrollbar-gutter:stable у порта делает её постоянной — иначе на короткой
   переписке лента была бы 305, а полоса 296.
   Грань и заливка переехали с полосы на .tc-cmt-kol: линия обязана обрываться
   на 1010, а не на 1390. */
.task-inline .tc-cmt-sticky{flex:none;position:static;bottom:auto;z-index:auto;
  margin:0;padding:8px 0 0;border-top:1px solid var(--line);background:var(--surface);
  box-sizing:border-box;align-self:flex-start;width:calc(100% - 9px)}
.task-inline .tc-cmt-kol{min-width:0}
/* полоса прокрутки порта резервируется ВСЕГДА — иначе ширина ленты гуляет от
   длины переписки, и признак «полоса = лента» краснел бы через раз */
.task-inline .tc-port{scrollbar-gutter:stable}

/* ── ПОДВАЛ И «ВСЯ ИСТОРИЯ» — В КОЛОНКЕ КОНТЕКСТА ──
   .df перестал быть закреплённым подвалом карточки: 69 px на широкой и 177 на
   375 (кнопки складывались в три этажа) уходили под редкие действия. 01.09 он
   уехал ещё дальше — в группу ЕЩЁ панели «Подробно», и там у него свои поля
   (.kp-in>.df). Правила для снятой колонки контекста удалены вместе с ней. */

/* ── ДВА ПОРТА И КОЛОНКА НАБОРА: ОДИН ПОРОГ НА ДВОИХ ──
   Лента становится собственным окном и листается сама, действие и шапка стоят
   на месте, набор листается своей колонкой. Условия оба обязательны: без
   min-height ленте остаются десятки пикселей, без ширины две колонки не влезают.
   ⚠️ ПОРОГ ШИРИНЫ ПОДНЯТ С 760 ДО 1100 (02.09) — И ЭТО ПОЧИНКА, А НЕ УЖЕСТОЧЕНИЕ.
   Пороги «сколько колонок» и «что закреплено» обязаны совпасть: разведи их, и на
   полосе «контейнер 760–1099 при экране ≥800» (браузер 1024×900) сетка получила
   бы фиксированную высоту строки, а набор поехал бы во вторую, неявную строку с
   auto-высотой — колонка растянулась бы на высоту ленты внутри одного окна.
   Ровно эта болезнь описана у снятого блока «ДВЕ КОЛОНКИ НА НИЗКОМ ЭКРАНЕ»
   ниже: контекст уезжал на 3000–4000 px.
   Цена подъёма названа числом и она в плюс: замер 01.09 на 1024×768 — два порта
   дают ленте 271 px (49,9 % окна), один порт 396 px (73 %). На полосе 760–1099
   лента становится ШИРЕ, а не уже, и набор просто течёт под ней внутри того же
   порта — один короткий свайп. */
@media(min-height:800px){
  @container kartochka (min-width:1100px){
    /* порт распускается: шапка снова закреплена, сетка делит остаток */
    .task-inline .tc-port{display:contents}
    .task-inline .tc-grid.v3{flex:1 1 auto;min-height:0;grid-template-rows:minmax(0,1fr)}
    .task-inline .tc-grid.v3 .tc-col{min-height:0;overflow-y:auto}
    /* ⚠️ flex:none КАЖДОМУ БЛОКУ КОЛОНКИ. Колонка стала окном с заданной высотой,
       а её дети — флекс-элементы со сжатием по умолчанию: без этой строки блоки
       ужимаются вместо того, чтобы уехать под прокрутку. Тот же класс, что уже
       ловили у подборщика «@» (шесть строк по 44 не влезли в потолок, нижняя
       ужалась до 28). */
    .task-inline .tc-grid.v3 .tc-col>*{flex:none}
    /* ⚠️ ЛЕНТЕ СВОЕЙ ПРОКРУТКИ НЕ ДАЁМ — ЛИСТАЕТСЯ ВСЯ КОЛОНКА.
       Замер 01.09 на карточке в 28 реплик, 1440×900: со своей прокруткой у ленты
       над ней постоянно стояли причина возврата 79, действие 52 и подпись 15 с
       отступами — 210 px из 461, ленте оставалось 251 px = 2,2 реплики и 37 %
       окна. Порог §6.2 требует ≥50 % и ≥3 единицы. Колонка целиком — это 461 px
       чата (4,1 реплики, 61 % окна) при том же содержимом. */
    /* min-height — тот же пол в половину окна, что и в режиме одного порта
       (правило «КОРОТКАЯ ПЕРЕПИСКА» ниже): здесь оно повторено, потому что
       правило блока идёт позже и специфичнее, а обнулять пол нельзя — вернётся
       дыра в 240 px между последней репликой и полем ответа. */
    .task-inline .tc-grid.v3 .tc-col-left #tcCommentsList{overflow:visible;
      min-height:calc(var(--kartochka-okno) * .5)}
    /* ГЛАВНОЕ ДЕЙСТВИЕ НЕ УЕЗЖАЕТ: липнет к верху колонки (§4.6 п.7 — одно
       главное действие первичной кнопкой). Стоит 52 px один раз, а не 210. */
    .task-inline .tc-grid.v3 .tc-col-left .tc3-act{position:sticky;top:0;z-index:3;
      background:var(--surface);padding-bottom:6px}
    /* внутренние потолки списков снимаем: колонка сама стала окном, и потолок
       внутри окна давал третий уровень прокрутки (352 и 404 внутри 300–500) */
    .task-inline .subs .subs-list,.task-inline #docBlockTC .doclist{max-height:none;overflow:visible}
    /* ═══ КОЛОНКА НАБОРА — ЕДИНСТВЕННОЕ МЕСТО В ФАЙЛЕ, ГДЕ КОЛОНОК ДВЕ ═══════
       Порог 1100 ВЫВЕДЕН, А НЕ НАЗНАЧЕН. Material для expanded отдаёт
       поддерживающей области 30 %: 320 / 0,30 = 1067 px содержимого; содержимое
       = контейнер − 38 (поля .db 2×18), значит контейнер 1105 — берём 1100.
       Ниже панель законной не бывает: при пороге 900 на экране 1024 ленте
       осталось бы 592 px, а порт чтения там и так 302.
       Проверка по экранам: 1440×900 — контейнер 1392, есть; 1280×800 — 1235,
       есть; 1024×768 — 983 и высота 768, нет по обоим; 853×533 — нет.
       Просвет 24 — поля карточки 18 плюс полстроки.
       ⚠️ ЗАТЕМНЕНИЯ У НАБОРА НЕТ И БЫТЬ НЕ ДОЛЖНО. Он стоит РЯДОМ с лентой, а
       не поверх: Material прямо говорит, что modal side sheet «blocks
       interaction with the rest of the screen» — приём для телефона. Рабочий
       набор обязан быть доступен одновременно с перепиской. Затемнение остаётся
       только у двери «Подробно», за которой редкое и разрушительное. */
    /* ⚠️ ВТОРАЯ КОЛОНКА ОБЪЯВЛЯЕТСЯ ТОЛЬКО ТАМ, ГДЕ НАБОР ПРАВДА ЕСТЬ В
       РАЗМЕТКЕ. Стояло безусловное `1fr 320px`, и в режиме правки (набора нет,
       его место занимает анкета — card.vid.js, ветка editing) сетка честно
       резервировала 320 px пустоты плюс просвет 24: замер 02.09 на 1440 —
       детей у сетки 1, ширина 1010, справа 344 px мёртвого поля. Тот же
       разъезд краснил проверку 9 сторожа окна (tests/kartochka_okno.js:
       «контейнер >= 1100 и окно >= 800 → колонок ровно две») на исправной
       правке. :has уже применён в этом файле (.tc-comment:has(> …)). */
    .task-inline .tc-grid.v3:has(> .tc-col-nabor){grid-template-columns:minmax(0,1fr) 320px;gap:24px}
    /* ═══ ПОЛОСА ОТВЕТА ПОВТОРЯЕТ ГЕОМЕТРИЮ СЕТКИ — ОБА УСЛОВИЯ, НЕ ОДНО ═════
       Полоса — СОСЕД сетки и о ней ничего не знает, поэтому её колонки
       объявляются здесь же и под теми же двумя порогами (min-height:800px +
       контейнер ≥1100). Забыть высоту — и на 1440×700 сетка одноколоночная, а
       полоса ужалась бы до 1010 при ленте 1392.
       :has(.tc-col-nabor) — третье обязательное условие, ровно то же, что у
       сетки строкой выше: в режиме правки набора в разметке НЕТ (его место
       занимает анкета), лента там 1356, и без этой проверки полоса встала бы
       1010 при ленте 1356 — расхождение 346. Тот же брак уже ловили у самой
       сетки (мёртвое поле 344 px справа), предупреждение стоит выше.
       Вычет 344 = колонка набора 320 + просвет 24; девять пикселей полосы
       прокрутки здесь НЕ вычитаются: они лежат ВНУТРИ .tc-col-left, её ширина
       1010 их уже включает.
       ⚠️ ПЕРВАЯ СТРОКА — ПРО РЕЖИМ ПРАВКИ, И ОНА ОБЯЗАТЕЛЬНА. Там набора нет,
       колонка одна во всю сетку (1354), но прокручивается всё равно КОЛОНКА, а
       не порт: девятку вычитать нечего. Без неё замер 02.09 дал полосу 1345 при
       ленте 1354 — расхождение −9 ровно в том месте, которое ворота не видят
       (сторож окна мерит карточку вне правки). */
    .task-inline .tc-cmt-sticky{width:100%}
    .task-inline:has(.tc-grid.v3 > .tc-col-nabor) .tc-cmt-sticky{width:calc(100% - 344px)}
    /* набор в колонке отбит не чертой сверху, а линией слева */
    .task-inline .tc-col-nabor{border-top:0;margin-top:0;padding-top:0;
      border-left:1px solid var(--line);padding-left:20px}
    /* ═══ ГЛАВНАЯ ЗАЩИТА ОТ ВОЗВРАТА СВАЛКИ ═══════════════════════════════
       Прежняя колонка контекста была свалкой не потому, что широкая, а потому,
       что прокручивалась ВСЛЕПУЮ целиком: 1228 px содержимого при 444 видимых,
       и «Удалить навсегда» лежало где-то там. Здесь колонка НЕ прокручивается
       вовсе. Прокручивается ровно одна вещь — список шагов, и он для этого и
       заведён: список с видимой полосой прокрутки читается списком, а не
       спрятанным низом. Приоритет, «в помощь» и поле «Добавить шаг…» видны
       всегда, на любой длине списка.
       Уровней прокрутки при этом по-прежнему два: страница → список. Колонка
       сама портом не становится (overflow:hidden), поэтому третьего нет.
       Замер 02.09 на карточке 620 (8 шагов, самая длинная на стенде): список
       694 px при 217 видимых. Свалка мерилась бы иначе — по тому, сколько
       ОРГАНОВ уехало из виду: здесь ноль, все четыре предмета на экране. */
    .task-inline .tc-grid.v3 .tc-col-nabor{overflow:hidden;display:flex;flex-direction:column}
    /* ⚠️ flex:0 1 auto, А НЕ flex:1 1 auto И НЕ flex:none — ОБА КРАЙНИХ ЗНАЧЕНИЯ
       БРАК, И ОДИН ИЗ НИХ НЕВИДИМ ВОРОТАМ.
       Было 1 1 auto: блок шагов растягивался на весь остаток колонки при любом
       числе шагов — 292 px из 429 и при восьми шагах, и при одном. Ровно это
       владелец назвал «две задачи занимают всё окно»: на карточке 787 с двумя
       шагами под последней строкой оставалось 42 px пустоты, на 622 с одним —
       108 px.
       Поставить flex:none нельзя: ограниченную высоту списку даёт цепочка
       #subBlockTC → .subs → .subs-list, и порванное верхнее звено оставляет
       список расти по содержимому. Своей полосы прокрутки он тогда не получает,
       а колонка объявлена overflow:hidden — нижние шаги стали бы физически
       недостижимы. Проверка 13 сторожа окна этого НЕ УВИДИТ: она меряет
       scrollHeight−clientHeight САМОГО .subs-list, а у неограниченного элемента
       они равны, и слепая прокрутка вышла бы 0 — зелено на живом дефекте.
       0 1 auto даёт оба свойства сразу: по содержимому, когда влезает; со своей
       прокруткой, когда нет. */
    .task-inline .tc-grid.v3 .tc-col-nabor>#subBlockTC{flex:0 1 auto;min-height:0;display:flex}
    .task-inline .tc-grid.v3 .tc-col-nabor .subs{flex:1 1 auto;min-height:0;
      display:flex;flex-direction:column;width:100%}
    .task-inline .tc-grid.v3 .tc-col-nabor .subs>*{flex:none}
    .task-inline .tc-grid.v3 .tc-col-nabor .subs-list{flex:1 1 auto;min-height:44px;
      max-height:none;overflow-y:auto}
    /* ═══ ИМЯ ШАГА В КОЛОНКЕ — ДВЕ СТРОКИ, ДАЛЬШЕ МНОГОТОЧИЕ ═══════════════
       Признак №25 требует, чтобы слепая прокрутка списка шагов не превышала
       высоту колонки (434). Замер 02.09 на 620 (8 шагов): 694 при видимых
       195 — слепых 499. Первые 44 снял row-gap (см. блок @container shagi),
       остальное — имена, разливающиеся на три-четыре строки в 192 px ширины:
       колонка в 320 px не место для абзаца, это список.
       Режем ТОЛЬКО имя и ТОЛЬКО здесь: чип этапа, причина возврата и «кто
       сделал · когда» остаются видны целиком, а на телефоне и на узкой
       карточке (там список не прокручивается вовсе) подрезки нет. Полное имя —
       в title строки; колонка живёт лишь при контейнере ≥1100 и окне ≥800,
       то есть на экране с мышью, где подсказка работает.
       После правки: 610 при видимых 195 — слепых 415 из 434.
       ⚠️ 02.09 ПОДРЕЗКА ПЕРЕЕХАЛА В БАЗОВОЕ ПРАВИЛО .sub-tx>.sub-nm И СТАЛА
       ОДНОЙ СТРОКОЙ, а не двумя, и не только в колонке. Причина: строка шага
       сжата до одного этажа, и вторая строка имени сама по себе делала бы
       её 63 px вместо 44 — признак «строка ≤48» краснел бы на длинных
       индонезийских названиях. Полное имя — в title строки и в шапке
       мини-листа сдачи. Здесь правило снято, чтобы -webkit-box не отменял
       многоточие базового. */
    /* ═══ ЛИСТ «ПОЗВАТЬ В ПОМОЩЬ» РАСКРЫВАЕТСЯ В КОЛОНКЕ И ВЫШЕ ЕЁ САМОЙ ═══
       ⚠️ БРАК, ПОЙМАННЫЙ ЗАМЕРОМ 02.09, И ЭТО РОВНО ЖАЛОБА «ВЫПАДАЮЩЕЕ НЕ
       ВЫПАДАЕТ». Форма помощников не попап и не лист вне потока: State.tcHelpAsk
       раскрывает её ПРЯМО В МЕСТЕ блока (card.vid.js, tcHelpersBlock). В колонке
       она стала 299×514 при колонке 320×429, а колонка объявлена overflow:hidden
       ради запрета слепой прокрутки — кнопка «Позвать» легла на 114 px НИЖЕ низа
       колонки, без единой полосы прокрутки. Нажал «Позвать в помощь» — форма
       открылась и её нечем отправить.
       Лечится сменой того, ЧТО прокручивается, а не отменой запрета: пока форма
       открыта, единственным прокручиваемым становится сама колонка (полоса
       видна, форма достаётся целиком), а список шагов течёт в потоке. Уровней
       прокрутки по-прежнему два: страница → колонка. Закрыли форму — вернулось
       прежнее устройство: колонка прибита, листается только список шагов. */
    .task-inline .tc-grid.v3 .tc-col-nabor:has(.helpask){overflow-y:auto}
    .task-inline .tc-grid.v3 .tc-col-nabor:has(.helpask)>#subBlockTC{flex:none;display:block}
    .task-inline .tc-grid.v3 .tc-col-nabor:has(.helpask) .subs{display:block}
    .task-inline .tc-grid.v3 .tc-col-nabor:has(.helpask) .subs-list{flex:none;
      max-height:none;overflow:visible}
  }
}

/* ── БЛОК «ДВЕ КОЛОНКИ НА НИЗКОМ ЭКРАНЕ» СНЯТ ВМЕСТЕ С КОЛОНКОЙ ──
   Он лечил конкретную болезнь: на полосе «карточка >= 760 и экран < 800»
   колонка контекста растягивалась на высоту ленты, и «Где» уезжало на 3000–4000 px.
   Колонки больше нет ни на одной ширине — весь контекст за дверью панели,
   расстояние до любой его группы — одно нажатие и ноль пикселей прокрутки.
   Сторож окна переписан тем же ходом (tests/kartochka_okno.js, проверки 9 и 11). */

/* ── КОРОТКАЯ ПЕРЕПИСКА: ОКНО НЕ СХЛОПЫВАЕМ, ПУСТОТУ УБИРАЕМ ВНУТРЬ ЛЕНТЫ ──
   Замер 01.09 на карточке в 2 реплики (1440×900): лента занимала свою
   собственную высоту 219 px из окна 675 — 32 %, ниже порога §6.2, и между
   последней репликой и полем ответа зияла дыра в 240 px. Даём ленте пол в
   половину окна: место под чат ВЫДЕЛЕНО всегда, а реплики прижаты к низу — как
   в мессенджере, свежее у поля ответа, пустота уходит вверх и читается как
   «переписка только началась».
   ⚠️ Прижимаем margin-top:auto у первой плитки, а НЕ justify-content:flex-end:
   у флекс-колонки с прокруткой flex-end отрезает начало содержимого — верхние
   реплики становятся недостижимы прокруткой. Известная ловушка, проверять на
   длинной переписке. Окно при этом НЕ схлопывается под короткую задачу:
   владелец просил один стабильный комфортный размер, прыгающий от карточки к
   карточке размер — это «раскладка перерисовывается под руками», §8. */
.task-inline #tcCommentsList{min-height:calc(var(--kartochka-okno) * .5)}
.task-inline #tcCommentsList>:first-child{margin-top:auto}
/* ── ПУСТАЯ КАРТОЧКА ОТДАЁТ СВОЁ ПУСТОЕ МЕСТО ЗАПОЛНЕНИЮ ──────────────────────
   Жалоба владельца дословно: «У тебя карточка создаётся пустой! Ты заполнение
   карточки увеличил во времени».
   Замер 02.09 на карточке 1739 («Надо»): от низа строки «Дело» до первого
   содержательного пикселя 326 px на 1440 и 271 на 375 — 92–96 % блока ленты
   пустоты, и единственная строка «комментариев пока нет» прижата к самому низу
   полом в половину окна. §6 стиля: пустое обязано говорить ПРИЧИНУ и ДЕЙСТВИЕ.
   Пол снимается ровно там, где реплик нет вовсе, и место занимает блок
   заполнения. Появилась первая реплика — класс уходит, пол включается, лента
   ведёт себя как мессенджер. */
.task-inline #tcCommentsList.zapoln{min-height:0}
.task-inline #tcCommentsList.zapoln>:first-child{margin-top:0}
.tc-zapoln{border:1px dashed var(--line);border-radius:12px;padding:12px;margin:2px 0 0}
.tc-zapoln .z-t{font-size:13px;font-weight:600;color:var(--ink);margin-bottom:9px}
.tc-zapoln .z-ryad{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:9px}
/* подсказка — ОДНО нажатие: ставит значение и гаснет. Значение не пишется
   молча в базу: человек его подтверждает (Monday Item default values и Dalux
   «responsible… will be suggested automatically» делают то же самое на сервере,
   а сервер за границей этой правки). */
.tc-zapoln .z-b{flex:0 1 auto;min-height:44px;padding:0 12px;border-radius:11px;border:0;
  background:var(--accent-soft);color:var(--accent);font:inherit;font-size:12.5px;
  font-weight:700;cursor:pointer;white-space:nowrap;max-width:100%;overflow:hidden;
  text-overflow:ellipsis}
.tc-zapoln .z-b:hover{background:var(--accent);color:var(--on-accent)}
.tc-zapoln .z-b:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.tc-zapoln .sub-add{margin-top:0}
/* ── ПОЛКА: ЧИСЛО ШАГОВ ВО ВТОРОМ ЭТАЖЕ ПОЛОСЫ ОТВЕТА ──
   Стоит 0 px новой высоты: во втором этаже композера на 375 свободно 89 px из
   305. Живёт только там, где колонки набора нет, — иначе это второй экземпляр
   одного и того же числа (§4.6 п.4). Ведёт к набору одним нажатием. */
/* ПОЛКА ШАГОВ — теперь чип строки «Дело», а не второй этаж полосы ответа.
   Слово «Шаги» снято: значок галки его заменяет, а подпись живёт в title
   парой RU/ID. Замер: 76×44 (ID 92×44) → 52×44 в обоих языках. */
/* ⚠️ min-width ТУТ ОБЯЗАТЕЛЕН. Рост 44 стоял, ширины не было: у карточки с одним
   шагом содержимое «галка 13 + просвет 5 + цифра» давало коробку 42.6×44 —
   недобор 1.4 px по ширине, и сторож вёрстки печатал его на 375, 853 и 1024
   (замер 03.09, карточка 715). Норма 2.5.5 — 44 по ОБЕИМ сторонам. */
.tc4-polka{flex:none;min-height:44px;min-width:44px;justify-content:center;
  padding:0 9px;border-radius:9px;background:none;
  border:0;color:var(--ink-2);font:inherit;font-size:11.5px;font-weight:700;
  cursor:pointer;white-space:nowrap;font-variant-numeric:tabular-nums;
  display:inline-flex;align-items:center;gap:5px}
/* ⚠️ размер svg задан здесь тоже — §4 стиля, «клякса» ловилась семь раз */
.tc4-polka svg{width:13px;height:13px;flex:none;stroke:currentColor;fill:none;
  stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
.tc4-polka:hover{background:var(--accent-soft);color:var(--accent)}
.tc4-polka:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
@media(min-height:800px){
  @container kartochka (min-width:1100px){ .task-inline .tc4-polka{display:none} }
}
/* ⚠️ ТАЧ-НОРМА ОРГАНА ВНУТРИ ДВЕРИ. Замер сторожа 02.09: select «После какой
   задачи идёт» — 174×37, недобор 7 px по высоте (§3, живая находка ловца).
   .ie-input задаёт padding и шрифт, роста не задаёт; у соседних .tc3-asg рост
   приходит из .tc3-chip, а строке .kv его брать неоткуда. */
.kp-in select.ie-input,.tc-col-nabor select.ie-input{min-height:44px}

/* ── ВСПЛЫВАЮЩИЕ СПИСКИ КАРТОЧКИ ВНУТРИ ОКНА ──
   Попап стадии 260×231, попап напоминания 340×92, выпадашка «Где» до 320 —
   раньше их спасала бесконечная высота карточки: клип .db лежал за тысячи
   пикселей. Теперь карточка — окно в 280–720 px, а строка шапки со своими
   якорями едет внутри порта, и попап, открытый у нижнего края, срезался бы
   (замер до этой строки на 853×533: из 231 px попапа стадии было видно 162).
   Даём потолок от того же числа, что и окно, и свою прокрутку — срезки нет ни
   на одной высоте, а все четыре стадии остаются доступны (§7: свернуть можно,
   убрать нельзя). Плюс card.deystviya.js подводит открытый попап в видимую
   часть порта — потолок без подводки оставил бы его наполовину за краем. */
.task-inline .tc4-st .tc4-rem-pop{
  max-height:calc(var(--kartochka-okno) - 160px);overflow-y:auto}
.task-inline .tc3-pick .pm{max-height:min(320px,calc(var(--kartochka-okno) - 160px))}

/* ── ЛЕГАСИ-КОНТЕКСТ: карточка, зажатая в столбик колонки канбана ──
   ⚠️ Сброс стоит ВНЕ всяких условий. Раньше он лежал внутри @media(min-width:901px),
   а потолок теперь безусловный: ниже 901 карточка в колонке схлопнулась бы в
   окно шириной 300 px, где две области высоту честно не поделят. */
.col .task-inline{display:block;max-height:none;container-type:normal}

/* ═══ P1 §4 — зов в помощь как событие: ответ на чипе и контекст в шторке ═══ */
/* слово ответа приглашённого: ждёт / принял / не могу / ознакомился.
   Слово, не краска — краски заняты законом трёх каналов (§1). */
.helper-chip .hotv{font-size:10.5px;font-weight:600;color:var(--ink-2);
  background:var(--surface);border-radius:999px;padding:1px 7px;margin-left:4px;
  vertical-align:1px;white-space:nowrap}
.helper-chip .hotv.o-zhdyot{color:var(--accent)}
/* строка «срок + вид» в шторке зова: дата и переключатель действие/ознакомить */
.helpask .hp-row{display:flex;align-items:flex-end;gap:10px;flex-wrap:wrap}
.helpask .hp-srok{display:flex;flex-direction:column;gap:4px;min-width:0}
.helpask .hp-srok .ie-input{min-height:44px}
.helpask .hp-vid button{min-height:44px}

/* ═══════════════════════════════════════════════════════════════════════════
   ПЕРЕКЛАДКА КАРТОЧКИ 01.09 — ЧЕТЫРЕ ГРУППЫ, ОДНА ДВЕРЬ, ОКНО СДАЧИ
   Требование владельца дословно: «Все группы настроек, которые можно скрыть, —
   скрыть… Сдача так же и висит. Всё должно быть логично, интуитивно и удобно,
   сейчас всё сбоку в прокручивающемся меню. Строка написания текста — во всю
   длину карточки!»
   Раскладку задают стандарты и смысл: что человек пришёл сделать, как устроено
   внимание, по каким признакам вещи читаются группой. Подсчётов использования
   здесь нет ни одного — это прямой запрет владельца.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── ДЛИНА = СКОЛЬКО СДЕЛАНО (§1, третий канал) ──
   Было бейджем-строкой «сделано 4 из 8» 98×20 внутри имени. Стало полосой в
   4 px во всю ширину: тот же смысл, 16 px экономии, и обвязка перестаёт гулять
   от состояния карточки. Полоса рисуется ВСЕГДА, даже без шагов, — иначе
   раскладка прыгала бы на 4 px при каждом приезде данных (§8). */
.tc4-dlina{flex:none;height:4px;margin:2px 0 5px;border-radius:3px;background:var(--line);overflow:hidden}
.tc4-dlina>i{display:block;height:100%;width:0;border-radius:3px;background:var(--accent);
  transition:width .25s var(--ease)}

/* ── ДВЕРЬ В ПАНЕЛЬ «ПОДРОБНО» ──
   Дверь видна ВСЕГДА и это не спрятанная навигация: спрятанное теряет 20 %
   находимости и добавляет 15–39 % времени (NN/g, Hidden Navigation).
   ⚠️ ДВЕРЬ НАЗВАНА СЛОВОМ НА ЛЮБОЙ ШИРИНЕ. Здесь стояло
   `@container … {.tc4-dver .dv-w{display:none}}` — на телефоне от двери
   оставался знак «⋯» рядом с крестиком, а за этим знаком лежат 94 органа из
   138: где объект, кто делает, шаги, файлы, история, девять кнопок. Значок без
   подписи опознаётся ненадёжно (NN/g, Icon Usability), соседняя цель того же
   вида закрывает карточку — человек не догадывался, и работу за это вернули.
   Цена названа числом: слово «Подробно / Rincian» вместо знака стоит имени
   задачи ~30 px на 375 (замер в отчёте). Имя и без того в одну строку с
   многоточием и раскрывается по тапу — тридцать пикселей его не ломают,
   а безымянная дверь ломала всю панель. */
.tc4-dver{flex:none;min-height:44px;min-width:44px;padding:0 13px;border-radius:12px;
  background:var(--surface-2);color:var(--ink-2);font-size:13px;font-weight:600;
  display:inline-flex;align-items:center;justify-content:center;cursor:pointer;
  white-space:nowrap;transition:background .15s,color .15s}
.tc4-dver:hover,.tc4-dver.on{background:var(--accent-soft);color:var(--accent)}
@container kartochka (max-width:759.98px){
  .task-inline .tc4-dver{padding:0 9px;font-size:12px}
}

/* ── ЧИП ДЕЙСТВИЯ: ГЛАВНОЕ ДЕЙСТВИЕ КАРТОЧКИ, ОДНО НА ЭКРАН (§2) ──
   Крупное и рядом с точкой внимания (NN/g, закон Фиттса). Ростом ровно 44 —
   тач-норма органа; было 52 у снятого ряда над лентой. */
.tc4-do{flex:none;min-height:44px;padding:0 16px;border-radius:12px;cursor:pointer;
  font-size:13.5px;font-weight:700;display:inline-flex;align-items:center;justify-content:center;
  transition:background .15s,transform .12s}
.tc4-do.glav{background:var(--accent);color:var(--on-accent);box-shadow:var(--sh-1)}
.tc4-do.glav:hover{background:var(--accent-hover)}
.tc4-do.vtor{background:var(--surface-2);color:var(--ink)}
.tc4-do.vtor:hover{background:var(--accent-soft);color:var(--accent)}
.tc4-do:active{transform:translateY(1px)}
.tc4-do:focus-visible{outline:2px solid var(--accent);outline-offset:1px}

/* ── АДРЕС: СВОЯ СТРОКА НАД НАЗВАНИЕМ, НА ВСЕХ ШИРИНАХ ──────────────────────
   ⚠️ ЧИП «ГДЕ» В СТРОКЕ «ДЕЛО» И ЕГО ПОРОГ ПО ШИРИНЕ СНЯТЫ 02.09 ВМЕСТЕ С ТРЕМЯ
   КАРАНДАШАМИ ИЗ СВОЙСТВ. Возможность не потеряна — у неё стало ОДНО место
   вместо трёх: было «чип-только-чтение на самой широкой карточке» плюс «три
   безымянных карандаша 44×44 за дверью», стало три слова-цели в закреплённой
   строке, и каждое открывает свой список на месте.
   Почему строка, а не чип: у чипа адрес был виден ТОЛЬКО на 1440 — на 1024, 853
   и 375 бригадир не видел, куда идти, вовсе. Локация обязательна у Procore
   (Location), Fieldwire («Level 4 / Unit 101») и Dalux; Jira печатает крошку над
   заголовком. Строка ДАННЫХ, а не орган: рост --h-data 30 — названное
   исключение §3 (норма 44 про органы; норма AA 2.5.8 требует 24×24 — держим).
   Цена названа числом: 10–15 px порта чтения на любой ширине, из них 8
   возвращает полоса длины, переехавшая сюда подчёркиванием. */
/* ⚠️ flex:none СТРОКЕ. Строка — флекс-элемент колонки .db, а у флекс-элемента
   сжатие включено по умолчанию: при потолке карточки колонка ужимала строку с
   собственных 44 обратно до min-height 30, и слово-цель ростом 44 ВЫЛЕЗАЛО из
   своей строки на 7 px вверх и вниз (замер 03.09: строка 127.75…157.75, слово
   120.75…164.75). В покое наложения не видно — фона у слова нет; при наведении
   и раскрытии фон появляется и ложится на крошку и название. Тот же класс, что
   уже ловили у колонки набора и у подборщика «@». */
.tc4-adres{display:flex;align-items:center;gap:2px;flex:none;min-height:30px;margin:0;position:relative;
  flex-wrap:nowrap;min-width:0;font-size:12.5px;font-weight:600;color:var(--ink-2)}
/* полоса длины ЛЕЖИТ ВНУТРИ строки адреса подчёркиванием и стоит 0 px высоты:
   в 30 px строки текст занимает 12,5, снизу свободно с запасом. Наложения нет —
   текстовые строки кончаются выше полосы (проверено сторожем вёрстки). */
.tc4-adres>.tc4-dlina{position:absolute;left:0;right:0;bottom:0;margin:0}
.tc4-adres .sp{flex:none;color:var(--ink-3);padding:0 1px}
/* ⚠️ ПОЛ ЯЧЕЙКИ 44, А НЕ 24: под словом-целью ростом 44 ячейка не имеет права
   ужиматься уже нормы касания. Три ячейки по 44 плюс две стрелки — 172 px из
   305 на 375, место есть. Ниже пола слово всё так же уходит в многоточие. */
.tc4-adres .tc3-cell{flex:0 1 auto;min-width:44px}
.tc4-adres .tc3-pick{min-width:0;display:flex}
/* слово И ЕСТЬ подпись цели: безымянных значков в адресе нет (NN/g, Icon
   Usability — значок без подписи опознаётся ненадёжно; за дверь «⋯» без слова
   работу уже возвращали). Уровень пути говорит aria-label. */
/* ⚠️ РОСТ 44, А НЕ 30, И ЭТО ИСПРАВЛЕНИЕ, А НЕ ВКУСОВЩИНА.
   Строка адреса объявлена выше «строкой данных» и потому стояла ростом
   --h-data 30. Но нажимаемое слово — не данные: <summary> ОТКРЫВАЕТ список,
   то есть это переключатель из перечня §3 («кнопки, чипы, переключатели, поля,
   галки»), и признак брака карточки говорит прямо: орган ниже 44 — брак.
   Замер 02.09 сторожем вёрстки на всех четырёх ширинах: tcAdr_*_proj 175.9×30,
   _obj 129.7×30, _stage 56.9×30 — три промаха в каждом прогоне, на 375 те же
   три. Данными в строке остаётся только .ad-txt (нет права менять) — он и
   держит 30, потому что его никто не жмёт.
   Цена: +14 px строки один раз на карточку, на любой ширине. */
.tc4-adres .tc3-pick>summary{list-style:none;cursor:pointer;min-height:44px;min-width:44px;
  padding:0 6px;border-radius:8px;display:inline-flex;align-items:center;gap:5px;
  color:var(--ink-2);background:none;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis;transition:background .15s,color .15s}
.tc4-adres .tc3-pick>summary::-webkit-details-marker{display:none}
.tc4-adres .tc3-pick>summary:hover{background:var(--accent-soft);color:var(--accent)}
.tc4-adres .tc3-pick[open]>summary{background:var(--accent-soft);color:var(--accent)}
.tc4-adres .tc3-pick>summary:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.tc4-adres .tc3-pick>summary .nm{min-width:0;overflow:hidden;text-overflow:ellipsis}
/* пустое значение говорит ДЕЙСТВИЕ, а не молчит (§6): «выбрать» вместо «—» */
.tc4-adres .tc3-pick>summary .nm.pusto{color:var(--accent);font-weight:700}
.tc4-adres .ad-txt{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:0 6px}

/* ── ЗОВ В ПОМОЩЬ: ВИДЕН ПОЗВАННОМУ НА ЛЮБОЙ ШИРИНЕ ──
   Заливка янтарём только пока ответа ждут (--st-review — та же пара, что у
   метки «Вернули»: своего цвета зов не заводит, §1). Ответил — чип остаётся
   тихим следом состояния. */
.tc4-zov{flex:0 1 auto;min-width:0;min-height:44px;padding:0 12px;border-radius:11px;
  border:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;
  background:var(--surface-2);color:var(--ink-2);font:inherit;font-size:12.5px;font-weight:700;
  overflow:hidden;white-space:nowrap;text-overflow:ellipsis;transition:background .15s,color .15s}
.tc4-zov.zhdyot{background:var(--st-review-bg);color:var(--st-review)}
.tc4-zov:hover{background:var(--accent-soft);color:var(--accent)}
.tc4-zov:focus-visible{outline:2px solid var(--accent);outline-offset:1px}

/* ── «ВЕРНУЛИ» — МЕТКОЙ НА ЧИПЕ СТАДИИ ──
   Возврат это «В работе» ПЛЮС метка, а не пятое состояние доски. Янтарь —
   заливка стадии «на проверке» по §1; своего цвета метка не заводит. */
.tc4-st>summary .tc4-st-vz{flex:none;background:var(--st-review-bg);color:var(--st-review);
  border-radius:999px;padding:2px 7px;font-size:10.5px;font-weight:700;white-space:nowrap}

/* ── «ДЕЛАЕТ» И «СЛЕДИТ»: РОВНО ОДИН ЭКЗЕМПЛЯР НА ЭКРАН ──
   На широкой карточке они в строке «Дело», на узкой — в СВОЙСТВАХ панели.
   Оба места в разметке есть всегда, видно всегда одно: разрезать по ширине
   можно только так — ветки по ширине карточки в JS завести нечем. */
.tc4-lyudi{display:contents}
@container kartochka (max-width:759.98px){ .task-inline .tc4-lyudi{display:none} }
.kp-lyudi{display:flex;gap:7px;flex-wrap:wrap;margin:8px 0 2px}
.kp-lyudi>*{flex:1 1 150px;min-width:0}
@container kartochka (min-width:760px){ .task-inline .kp-lyudi:not(.vsegda){display:none} }

/* ── АНКЕТА ПРАВКИ ЦЕЛИКОМ В ПОТОКЕ ──
   В режиме правки панели нет вовсе: иначе название правилось бы в шапке,
   приоритет — за дверью, а «Сохранить» — в последней группе панели. Форма,
   разрезанная надвое дверью, и была бы новой свалкой. */
.tc-edit-form{margin:10px 0 14px}
.tc-edit-form>.df{padding:12px 0 0;margin-top:10px}

/* ═══ ПАНЕЛЬ «ПОДРОБНО» ═══════════════════════════════════════════════════
   Один уровень — дверь, второй — группы. Третьего нет: третий губит
   применимость (NN/g, Progressive Disclosure). Панель НАКРЫВАЕТ ленту и не
   сжимает её — сжатие это перекладка под руками, прямой запрет §8.
   Живёт ВНУТРИ .task-inline: у карточки стоит contain:layout от
   container-type, поэтому абсолютный потомок считает координаты от неё, а не
   от экрана, и наружу карточки панель не вылезает. */
.kart-panel{position:absolute;inset:0;z-index:9;display:block}
.kart-panel[hidden]{display:none}
.kp-scrim{position:absolute;inset:0;background:rgba(30,26,20,.34)}
.kp-box{position:absolute;top:0;right:0;bottom:0;width:min(460px,74cqw);
  background:var(--surface);box-shadow:var(--sh-3);border-left:1px solid var(--line);
  border-radius:var(--r3) 0 0 var(--r3);display:flex;flex-direction:column}
/* узкая карточка — нижний лист: приём Material 3 Bottom sheets */
@container kartochka (max-width:759.98px){
  .task-inline .kp-box{top:auto;left:0;right:0;bottom:0;width:auto;max-height:88%;
    border-left:0;border-top:1px solid var(--line);border-radius:var(--r3) var(--r3) 0 0}
}
.kp-head{flex:none;display:flex;align-items:center;gap:10px;padding:6px 8px 6px 14px;
  border-bottom:1px solid var(--line)}
.kp-t{flex:1;min-width:0;font-size:11px;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;color:var(--ink-2)}
.kp-x{flex:none;width:44px;height:44px;border-radius:12px;background:var(--surface-2);
  display:grid;place-items:center;cursor:pointer}
.kp-x:hover{background:var(--line)}
.kp-x svg{width:19px;height:19px;stroke:var(--ink-2);fill:none;stroke-width:2.2;stroke-linecap:round}
/* ⚠️ overscroll-behavior:contain ЗДЕСЬ РАЗРЕШЁН И ТОЛЬКО ЗДЕСЬ (плюс окно
   сдачи): под панелью лежит ЧУЖАЯ поверхность — лента карточки, — и палец не
   должен уезжать туда. Внутри страницы это правило запрещено §8, и в карточке
   его больше нет нигде. */
/* ⚠️ ПРОКРУЧИВАЕТСЯ ТЕЛО ОТКРЫТОЙ ГРУППЫ, А НЕ ВСЯ ПАНЕЛЬ. Иначе раскрытые
   ШАГИ (892 px на карточке 620) выталкивали бы четыре остальных имени за низ
   листа: замер на 375 — «Свойства», «Файлы», «История» и «Ещё» становились
   недостижимы пальцем, elementFromPoint в их центре возвращал не их. Пять имён
   обязаны быть видны всегда — это и есть второй уровень раскрытия; уезжать под
   прокрутку имеет право только содержимое одной открытой группы.
   Заодно снимается третий уровень прокрутки: страница → тело группы, и всё. */
.kp-body{flex:1 1 auto;min-height:0;overflow:hidden;padding:2px 14px 14px;
  display:flex;flex-direction:column}
.kp-grp{flex:none;border-top:1px solid var(--line);min-height:0}
.kp-grp:first-child{border-top:none}
.kp-grp.on{flex:1 1 auto;display:flex;flex-direction:column}
.kp-grp.on>.kp-in{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain}
.kp-sum{width:100%;display:flex;align-items:center;gap:9px;min-height:44px;padding:0 2px;
  background:none;border:0;text-align:left;font:inherit;font-size:13.5px;font-weight:600;
  color:var(--ink);cursor:pointer}
.kp-sum:hover{color:var(--accent)}
.kp-sum:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.kp-nm{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* ЧИСЛО В ПОДПИСИ СВЁРНУТОЙ ГРУППЫ — §4.6 п.8: разворачивать ради взгляда не
   надо. Многоточие вместо нуля, пока данные не приехали: ноль был бы враньём. */
.kp-sum .cnt{flex:none;background:var(--surface-2);color:var(--ink-2);font-size:11px;
  font-weight:700;padding:2px 8px;border-radius:999px;font-variant-numeric:tabular-nums}
.kp-ch{flex:none;display:grid;place-items:center;color:var(--ink-2);
  transition:transform .2s var(--ease)}
.kp-ch svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2}
.kp-grp.on>.kp-sum{color:var(--accent)}
.kp-grp.on .kp-ch{transform:rotate(180deg)}
.kp-in{padding:0 0 12px}
.kp-in[hidden]{display:none}
.kp-in>.df{padding:0;margin:0;border-top:0}
.kp-in>.df .btn{flex:1 1 150px;justify-content:flex-start}
/* группа ЕЩЁ: разрушительное отделено своим голосом и своим местом — последним
   (§7, Apple HIG Action sheets), вне дуги большого пальца. */
.kp-in>.df .btn.danger{order:9}
.kp-in .subs{border-top:0;margin-top:0;padding-top:0}
.kp-in .sect-lbl{margin-top:10px}
/* ⚠️ ТРЕТЬЕГО УРОВНЯ ПРОКРУТКИ НЕ БЫВАЕТ. У списка шагов и списка документов
   свои потолки с прокруткой — они спасали бесконечную колонку контекста. В
   панели прокручивается ТЕЛО открытой группы, и потолок внутри него дал бы
   прокрутку в прокрутке в прокрутке: страница → тело группы → список. Снимаем.
   ⚠️ ВЕС СЕЛЕКТОРА ЗДЕСЬ — НЕ КОСМЕТИКА, НА НЁМ УЖЕ ОБОЖГЛИСЬ. Стояло
   `.kp-in .doclist` (0,2,0) против `#docBlockTC .doclist` (1,1,0) — правило
   проигрывало по весу и НЕ РАБОТАЛО: внутри ФАЙЛОВ на телефоне оставалась
   прокрутка 352 px внутри тела группы в ~240 px. В отчёте при этом было
   написано «снято». Победить обязан селектор, а не порядок строк: у документов
   берём тот же id (1,2,0), у шагов — на класс длиннее (0,3,0). */
.kp-in .subs .subs-list,.kp-in #docBlockTC .doclist{max-height:none;overflow:visible}

/* ═══ ОКНО СДАЧИ ═══════════════════════════════════════════════════════════
   Живёт в document.body, а не в карточке: у .task-inline стоит contain:layout
   от container-type, и окно, положенное внутрь, считало бы высоту от карточки
   (585 px на 375, а не 812) и рисовалось бы НИЖЕ .botnav и #fab при любом
   z-index. Не #drawer: там живёт openModal, и State.overlay="modal" стирал бы
   карточку под живым окном.
   Высота от dvh, а не от svh: под поднятой клавиатурой окно обязано ужаться,
   иначе поле отчёта уезжает за верхний край. Дёрганье адресной строки тут не
   мешает — окно живёт секунды, а не всю прокрутку. */
.kartokno{position:fixed;inset:0;z-index:var(--z-kartokno);display:flex;
  align-items:flex-end;justify-content:center}
.ko-scrim{position:absolute;inset:0;background:rgba(30,26,20,.46)}
.ko-box{position:relative;z-index:1;width:min(560px,100%);max-height:min(86dvh,620px);
  background:var(--surface);box-shadow:var(--sh-3);display:flex;flex-direction:column;
  border-radius:var(--r-drawer) var(--r-drawer) 0 0}
@media(min-width:641px){
  .kartokno{align-items:center}
  .ko-box{border-radius:var(--r-drawer);max-height:min(84dvh,640px)}
}
.ko-head{flex:none;display:flex;align-items:center;gap:10px;padding:6px 8px 6px 16px;
  border-bottom:1px solid var(--line)}
.ko-t{flex:none;font-size:11px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-2)}
.ko-n{flex:1;min-width:0;font-size:13px;font-weight:600;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* крестик 44, а не 36: тач-норма органа (§3) */
.ko-x{flex:none;width:44px;height:44px;border-radius:12px;background:var(--surface-2);
  display:grid;place-items:center;cursor:pointer}
.ko-x:hover{background:var(--line)}
.ko-x svg{width:19px;height:19px;stroke:var(--ink-2);fill:none;stroke-width:2.2;stroke-linecap:round}
.ko-body{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:12px 16px 16px}
.ko-body>.tc3-sheet{background:transparent;padding:0}
/* ПРИЧИНА ВОЗВРАТА — СТРОКОЙ ВНУТРИ ОКНА. С поднятой клавиатурой карточки под
   окном не видно вообще, а отчёт пишут именно по причине. Свёрнута: 36 px,
   раскрывается касанием. */
.ko-vz{background:var(--st-review-bg);border-radius:10px;border-left:3px solid var(--st-review);
  margin:0 0 10px}
.ko-vz>summary{list-style:none;cursor:pointer;min-height:36px;display:flex;align-items:center;
  padding:0 11px;font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;
  color:var(--st-review)}
.ko-vz>summary::-webkit-details-marker{display:none}
.ko-vz-t{padding:0 11px 9px;font-size:13px;line-height:1.45;color:var(--ink);white-space:pre-wrap}

/* СООБЩЕНИЕ СДАЧИ, К КОТОРОМУ ПРИВЁЛ ЧИП «РЕШИТЬ» — короткая подсветка, чтобы
   взгляд нашёл нужную реплику. Ничего не мигает и не прыгает (§8): одна
   плавная обводка на 1,6 с. */
.cycm-vzglyad{box-shadow:0 0 0 2px var(--accent)}

/* ═══ § СРОК: ПЕРВОЕ ОБЕЩАНИЕ ═══════════════════════════════════════════════
   Приписка под сроком: «Обещали 12.08 · переносов: 2». Появляется ТОЛЬКО у
   карточки, которой срок двигали, — обёртка .tc4-due2 в разметке тоже рождается
   только там, поэтому у всех остальных чип срока остаётся прежним до пикселя.
   Строка ДАННЫХ, а не орган управления: не кликается, ростом 14 px (§3 —
   норма 44 про кнопки и поля, данные остаются плотными).
   Цвета своего нет: --ink-2, как у остальных вторичных подписей. Смысл несут
   слово и число (WCAG 2.2 SC 1.4.1), заливки под перенос не бывает.
   ⚠️ flex у чипа внутри обёртки ПЕРЕБИВАЕТСЯ нарочно: .tc4-line .tc3-chip
   объявляет flex:1 1 150px, а в колоночной обёртке flex-basis стал бы ВЫСОТОЙ
   в 150 px — чип раздулся бы вчетверо. */
.tc4-line .tc4-due2{flex:1 1 150px;min-width:0;display:flex;flex-direction:column;gap:2px}
.tc4-line .tc4-due2 .tc3-chip{flex:0 0 auto;width:100%;min-width:0}
/* ⚠️ МНОГОТОЧИЯ ЗДЕСЬ НЕТ НАРОЧНО. С `white-space:nowrap` замер на 390 дал
   обрезку: коробка приписки 115 px против нужных ~170, и владелец на телефоне
   читал бы «Обещали 22.08 · пер…». Сторож такую обрезку не ловит (текст с
   многоточием обрезкой не считается) — поймал замер руками. Дата первого
   обещания и есть то, ради чего строку заводили; резать её нельзя, поэтому на
   узком экране строка честно уходит на второй ряд — тем же решением, что
   ступень 2 «лестницы сброса» выше: обрезанное слово хуже второй строки. */
.tc4-srok1{font-size:10.5px;line-height:1.3;color:var(--ink-2);padding-left:9px;
  white-space:normal;overflow-wrap:anywhere}

/* ═══ § ПРОГРЕСС ШАГОВ: ИЗ ЧЕГО ЦИФРА И ЧТО УБРАЛИ ═══════════════════════════
   Карточка «Прогресс шагов, который нельзя накрутить дроблением и удалением».
   Три надписи под полосой объясняют цифру БЕЗ наведения: на 375 наведения не
   бывает вовсе, и подсказка носителем смысла быть не может (NN/g).
   Строки — ДАННЫЕ, и они остаются плотными (§3 стиля, --h-data против --h-row).
   Орган здесь ровно один — «вернуть», и он обязан быть 44 px. */
.subs-pochemu{display:flex;flex-wrap:wrap;gap:2px 12px;margin:-5px 0 10px;
  font-size:11px;line-height:1.35;color:var(--ink-2)}
.subs-pochemu .sp-str{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.subs-pochemu .sp-ubr{font-weight:700;color:var(--ink)}

/* хвост списка: убранные шаги. Не работа, а след — поэтому под списком, тише
   живых строк и с отбивкой сверху, чтобы не читаться продолжением списка. */
.subs-ubr{margin-top:8px;padding-top:8px;border-top:1px dashed var(--line);
  display:flex;flex-direction:column;gap:2px}
.subs-ubr .su-row{display:flex;align-items:center;column-gap:11px;
  min-height:44px;padding:0 4px}
.subs-ubr .su-nm{flex:1;min-width:0;font-size:13px;line-height:1.35;color:var(--ink-2);
  text-decoration:line-through;text-decoration-thickness:1px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* ТАЧ-ЦЕЛЬ 44 — §3 стиля. Строчное действие: текст цветом акцента, без рамки и
   без заливки (§2), но коробка полноразмерная — иначе палец мимо. */
.sp-vernut{flex:none;min-width:44px;min-height:44px;padding:0 10px;
  border:0;background:transparent;color:var(--accent);
  font-size:13px;font-weight:600;line-height:1;cursor:pointer;border-radius:9px}
.sp-vernut:hover{background:var(--surface-2);color:var(--accent-hover)}
.sp-vernut:focus-visible{outline:2px solid var(--accent);outline-offset:1px}

/* ═══════════ § ПЕРЕПИСКА: ПЕРЕВОД ОДНОЙ КНОПКОЙ, ДЕНЬ ЛИПКИЙ, ДОКУМЕНТ В TG ═══
   Карточка «Переписка в карточке…», владелец 03.09. Три правки одной темы:
   перевод стал одним органом ленты, день — липким разделителем при прокрутке,
   у вложения появилось действие «В Telegram».
   ⚠️ ИМЕНА КЛАССОВ ВЫБРАНЫ ГРЕПОМ ПО ВСЕМ ТАБЛИЦАМ, а не на слух — это
   починенный брак `.fs-b` (см. предупреждение у .fotosmotr выше):
   `grep -rn "\.cmt-den\b" frontend/css/` и так по каждому из семи новых имён
   дал 0 совпадений до правки. */

/* ── ШАПКА РЕПЛИКИ БЕЗ КНОПКИ ПЕРЕВОДА — СТРОКА ДАННЫХ, А НЕ ОРГАН ──────────
   §3 стиля: норма 44 px — про ОРГАНЫ УПРАВЛЕНИЯ. В шапке чужой реплики органов
   не осталось вовсе (перевод уехал в шапку ленты), значит это строка данных и
   ей положена плотность --h-data, а не тач-норма. У СВОЕЙ реплики органы на
   месте — правка и удаление, — и там 44 остаются.
   Замер 03.09, 375 px, карточка 787: шапка чужой реплики 44 при содержимом 17.
   Правило на :has, а не на .theirs, потому что судит НАЛИЧИЕ ОРГАНА, а не
   сторону: вернут кнопку — вернётся и высота (на этом стоит «красное» карточки). */
.task-inline .tc-comment-h{min-height:26px}
.task-inline .tc-comment-h:has(.del),
.task-inline .tc-comment-h:has(.edt),
.task-inline .tc-comment-h:has(.tr-btn){min-height:44px}

/* ── ЕДИНСТВЕННЫЙ ОРГАН ПЕРЕВОДА — В ПОЛОСЕ ОТВЕТА, РЯДОМ СО СКРЕПКОЙ ──────
   ⚠️ СТОЯЛ НАД ЛЕНТОЙ И БЫЛ НЕДОСТИЖИМ. Карточка открывается на последней
   реплике, порт сразу внизу: замер приёмки 03.09 на 375 — верх кнопки −3138 px
   на карточке 787, −1156 на 715, −201 даже на 845 с четырьмя репликами.
   Липкая полоса над лентой достижимость чинит, но отнимает у чата 44 px
   навсегда, а правка затевалась ради обратного. Полоса ответа не отнимает
   ничего: она уже липкая и уже 44 px, третий орган встаёт в ту же строку и
   высоту не меняет (проверка 15 ЭТАЖ, потолок 56).
   Квадрат 44×44 со значком: слово «Перевод» стоило бы 77 px ширины из 198,
   которые полоса даёт полю ввода на 375. Подпись — парой в title/aria-label. */
.cmt-tr-tog{flex:none;width:44px;height:44px;padding:0;
  display:inline-flex;align-items:center;justify-content:center;
  border:0;border-radius:10px;background:transparent;color:var(--ink-2);
  cursor:pointer;transition:background .18s var(--ease),color .18s var(--ease)}
.cmt-tr-tog svg{width:19px;height:19px;stroke:currentColor;fill:none;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
.cmt-tr-tog:hover{background:var(--accent-soft);color:var(--accent)}
/* включённое состояние несёт НЕ ТОЛЬКО цвет: aria-pressed говорит читалке, а
   заливка акцентом — глазу (§1 стиля: акцент один, новых цветов не заводим) */
.cmt-tr-tog.on{background:var(--accent-soft);color:var(--accent)}
.cmt-tr-tog:focus-visible{outline:2px solid var(--accent);outline-offset:1px}

/* ── ПУЗЫРЬ ПОХУДЕЛ НА ДВА ПИКСЕЛЯ С КАЖДОЙ СТОРОНЫ ────────────────────────
   Разделители дня и шапка ленты — это плюс 250 px к ленте на карточке 787, и
   съеденный ими выигрыш надо было вернуть НЕ буквами, а полями. Набивка пузыря
   9/11 → 8/10 и просвет ленты 10 → 8: на 30 репликах это 30×2 + 29×2 = 118 px,
   а строка текста не тронута вовсе — `line-height:1.45` остаётся как есть.
   ⚠️ 1.45 → 1.35 ПРОБОВАЛИ И ОТВЕРГЛИ ЧИСЛОМ: за десять положений прокрутки
   реплик целиком выходило столько же (17 против 17), потому что перенос строк
   сдвигается и выигрыш съедается, — платить за ноль читаемостью нельзя
   (полтора межстрочья — норма набора и запас под WCAG 2.2 SC 1.4.12).
   Правило живёт под `.task-inline`, чтобы чужой чат «Моего» не задеть. */
.task-inline .tc-comment{padding:8px 10px}
.task-inline .tc-comments-list{gap:8px}

/* ── ДЕНЬ ЛИПКОЙ ПЛАШКОЙ (образец Telegram/WhatsApp) ───────────────────────
   `position:sticky; top:0` внутри ленты: порт прокрутки у карточки бывает
   разный (на широкой карточке высокого экрана лента сама себе окно, иначе её
   листает .tc-port), а sticky сам находит ближайший прокручиваемый предок —
   поэтому число порта тут не зашито ни одно.
   ⚠️ ФОН НЕПРОЗРАЧНЫЙ И РОВНО ТОТ, ЧТО ПОД ЛЕНТОЙ: сквозь плашку не должен
   просвечивать текст реплики, которая под неё уезжает.
   Высота 24 и подпись словом — строка данных, не орган: onclick тут нет, и
   сторож тач-целей эту строку не считает (§3, названное исключение). */
.cmt-den{position:sticky;top:0;z-index:3;align-self:center;flex:none;
  display:flex;align-items:center;justify-content:center;
  min-height:24px;max-height:28px;margin:0;padding:0 10px;
  border-radius:999px;background:var(--surface);color:var(--ink-2);
  font-size:11px;font-weight:700;letter-spacing:.02em;white-space:nowrap;
  box-shadow:0 1px 2px rgba(0,0,0,.06)}

/* ── ВЛОЖЕНИЕ: ПЛИТКА + «В TELEGRAM» ──────────────────────────────────────
   Одно нажатие — один документ — один адресат. Кнопка рядом с плиткой, а не
   внутри неё: нажатие на плитку открывает просмотр, и два действия в одной
   коробке путались бы. Тач-цель полные 44 (§3, WCAG 2.2 SC 2.5.8). */
.cmt-fbox{display:flex;align-items:center;gap:6px;min-width:0;max-width:100%}
.cmt-fbox>.cmt-file{min-width:0;flex:0 1 auto}
.cmt-tg{flex:none;width:44px;height:44px;border:0;border-radius:10px;
  background:var(--surface-2);color:var(--ink-2);display:grid;place-items:center;cursor:pointer;
  transition:background .18s var(--ease),color .18s var(--ease)}
.cmt-tg:hover{background:var(--accent-soft);color:var(--accent)}
.cmt-tg svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
.cmt-tg:focus-visible{outline:2px solid var(--accent);outline-offset:1px}

/* ── «В TELEGRAM» В ПРОСМОТРЩИКЕ ФОТО ─────────────────────────────────────
   Значком, а не словом: шестое слово в шапке на 375 не влезает, и проверка
   20 СМОТР покраснела бы обрезкой. Отступ auto забирает себе ПЕРВЫЙ орган
   справа — теперь это она, поэтому у следующих .fsm-b его снимаем. */
.fotosmotr .fsm-tg{margin-left:auto;width:44px;height:44px;min-width:44px;min-height:44px;
  padding:0;justify-content:center}
.fotosmotr .fsm-tg~.fsm-b{margin-left:0}
.fotosmotr .fsm-tg svg{stroke:currentColor;fill:none;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}

/* ═══ § НАЧАЛО РАБОТЫ — СТРОКА ПОД СРОКОМ ══════════════════════════════════
   Карточка «Дата начала видна на карточке, ставится в плане и на таймлайне».
   Тот же чип, что у срока, и намеренно НЕ красится ни просрочкой, ни «сегодня»:
   начало — это факт календаря, а тревога живёт на правом конце полосы. Подпись
   приглушена (--ink-2), поле даты наследует 44 px от .tc3-chip.due input.
   Строка рождается ТОЛЬКО когда есть что показать или что править: у зрителя
   без начала её нет вовсе, и чип срока остаётся прежним до пикселя. */
.tc3-chip.due.nach{background:var(--surface-2)}
.tc3-chip.due.nach .lbl{color:var(--ink-2);font-weight:600}
.tc3-chip.due.nach .val{font-weight:600}
