/* Оформление сервиса. Взято из docs/prototype.html - лейаут утверждён, и
   придумывать заново не надо. Ничего внешнего: ни CDN, ни шрифтов из сети.

   Отличие от прототипа одно: там страницы статические, а здесь живые формы,
   поэтому к готовым классам добавлены поля ввода, таблицы и служебные блоки -
   в той же палитре и тех же радиусах. */

:root{
  --bg:#f6f7f9; --panel:#fff; --ink:#1b1f24; --muted:#6b7280; --line:#e3e6ea;
  --accent:#2f6fed; --accent-soft:#eaf1fe;
  --done:#2e9e5b; --done-soft:#e7f5ec;
  --now:#e0a11b; --now-soft:#fdf4e0;
  --late:#d64545; --late-soft:#fdeaea;
  --wait:#7c6bd8; --wait-soft:#efecfb;
  --idle:#c3c8cf;
  /* Второй фон: наведённая строка, метка, панель раскрытой правки. Раньше
     каждое такое место писало #fafbfc или #eef0f3 руками, и тёмной темы из
     этого было не собрать. */
  --panel2:#f7f8fa;
  --grid:#eef1f5;
  --line2:#c8ced6;            /* граница под курсором */
  --синий:var(--синий);            /* третий приоритет */
  /* Текст на мягких плашках. Отдельными токенами: в тёмной теме тот же
     тёмно-зелёный на тёмно-зелёном не читается. */
  --done-ink:#1d7a44; --now-ink:#8a6410; --late-ink:#a82f2f;
  --wait-ink:#5847b8; --accent-ink:#1c4fb5;
  --тень:var(--тень);
  --тень-сильная:var(--тень-сильная);
  color-scheme:light;
}

/* Тёмная тема. Переключатель - в сайдбаре, выбор запоминается в браузере и
   применяется до первой отрисовки: иначе страница успевает моргнуть белым.

   Сайдбар и в светлой теме тёмный, поэтому здесь он почти не меняется -
   меняется всё остальное. */
html[data-theme="dark"]{
  --bg:#14171c; --panel:#1c2027; --ink:#e7eaee; --muted:#98a1ad; --line:#2c323b;
  --accent:#5b8dfa; --accent-soft:#1d2942;
  --done:#3fae6b; --done-soft:#16301f;
  --now:#d59a22; --now-soft:#332713;
  --late:#e05a5a; --late-soft:#37191a;
  --wait:#8f80e6; --wait-soft:#241f3d;
  --idle:#4b525c;
  --panel2:#21262e; --grid:#252b34; --line2:#3b434e;
  --синий:#5b9bea;
  --done-ink:#79d19c; --now-ink:#e6bb63; --late-ink:#f39a9a;
  --wait-ink:#b3a8f2; --accent-ink:#a8c4ff;
  --тень:rgba(0,0,0,.45);
  --тень-сильная:rgba(0,0,0,.55);
  color-scheme:dark;
}
*{box-sizing:border-box}
/* `hidden` обязан прятать. У блока с `display:grid` атрибут проигрывает
   правилу из таблицы стилей, и спрятанные поля формы события оставались на
   экране - при том, что скрипт отработал. */
[hidden]{display:none !important}

/* Переход между страницами вместо белой вспышки. Браузер по умолчанию
   перекрашивает окно в белое между уходом со страницы и первой отрисовкой
   новой; на тёмном сайдбаре это видно как моргание. Кто это умеет - покажет
   плавную смену, кто нет - просто перейдёт как раньше.

   Работает только на настоящей навигации между документами - вход, выход,
   ссылки с `hx-boost="false"`. Переходы внутри приложения идут подменой
   разметки и не анимируются вовсе: см. комментарий в `base.html`. */
@view-transition{navigation:auto}
@media (prefers-reduced-motion:reduce){
  ::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation:none}
}

/* Фон задан и на html: между документами красится именно он, и без этого
   вспышка остаётся даже с переходами. */
html{background:var(--bg)}

/* Полосу прокрутки не показываем. Список задач при фильтрации то длиннее, то
   короче страницы: полоса появлялась и исчезала, и вся страница прыгала вбок
   на её ширину. Прокрутка остаётся - колесом, клавишами, тачпадом, - исчезает
   только сама полоса. Внутренних блоков с прокруткой это не касается: там
   полоса и есть подсказка, что содержимое длиннее, чем видно. */
html{scrollbar-width:none}
html::-webkit-scrollbar,body::-webkit-scrollbar{width:0;height:0}
body{margin:0;font:14px/1.45 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Arial,sans-serif;
     color:var(--ink);background:var(--bg)}
a{color:var(--accent);text-decoration:none}
a:hover{text-decoration:underline}
code{font:12px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace;background:var(--grid);
     border-radius:4px;padding:1px 5px}
pre code{display:block;padding:10px 12px;overflow-x:auto}

/* ---------- каркас ---------- */
/* `minmax(0,1fr)`, а не `1fr`: у колонки грида ширина по умолчанию не
   меньше содержимого, и широкая доска канбана растягивала страницу за
   правый край экрана - вместе с ней уезжал и текст над ней. Теперь
   широкое прокручивается внутри себя. */
.app{display:grid;grid-template-columns:210px minmax(0,1fr);min-height:100vh}
.side{background:#151a21;color:#c9d1d9;padding:16px 0;position:sticky;top:0;height:100vh;
      display:flex;flex-direction:column;view-transition-name:сайдбар}
.main{view-transition-name:основное}
.brand{padding:0 18px 18px;font-weight:700;font-size:15px;color:#fff;letter-spacing:.2px}
.brand a{color:#fff;text-decoration:none}
.brand small{display:block;font-weight:400;font-size:11px;color:#7d8590;letter-spacing:0}
.nav{display:flex;flex-direction:column}
.nav a{display:flex;justify-content:space-between;align-items:center;padding:9px 18px;
       color:#c9d1d9;font-size:13.5px;text-decoration:none}
.nav a:hover{background:#1d242d;text-decoration:none}
.nav a.on{background:var(--accent);color:#fff}
.nav .cnt{font-size:11px;background:#2b333d;padding:1px 6px;border-radius:9px}
.nav a.on .cnt{background:rgba(255,255,255,.25)}
.nav.отступ{margin-top:16px}
.navgroup{padding:16px 18px 6px;font-size:10.5px;text-transform:uppercase;letter-spacing:.8px;color:#5c6673}
.who{margin-top:auto;padding:12px 18px;border-top:1px solid #262d36;font-size:12px;color:#8b949e}
.who a{color:#c9d1d9;text-decoration:none}
.who a:hover{color:#fff;text-decoration:underline}
.who form{margin:0}
.who-кнопки{display:flex;gap:6px;margin-top:6px}
.who button{background:transparent;border:1px solid #333c47;color:#8b949e;border-radius:6px;
            padding:3px 9px;font-size:11.5px}
.who button:hover{border-color:#4a5563;color:#c9d1d9}

.main{padding:20px 26px 60px;max-width:1500px}
/* Возврат в раздел. Подписью, а не кнопкой: это не действие над тем, что на
   экране, а выход из него, и спорить за внимание с «Собрать документ» ему
   незачем. Раньше выйти из карточки можно было только через сайдбар. */
.назад{display:inline-flex;align-items:center;gap:5px;font-size:12.5px;
       color:var(--muted);text-decoration:none;margin-bottom:10px}
.назад:hover{color:var(--accent);text-decoration:none}
.head{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;margin-bottom:14px;flex-wrap:wrap}
.head .acts{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
h1{font-size:20px;margin:0 0 2px}
h2{font-size:16px;margin:0 0 8px}
h3{font-size:14px;margin:0 0 8px}
.sub{color:var(--muted);font-size:12.5px}
.muted{color:var(--muted)}
.h5{font-size:11px;text-transform:uppercase;letter-spacing:.7px;color:var(--muted);margin:0 0 9px}
.note{font-size:12px;color:var(--muted);margin-top:10px;line-height:1.5}
.hide{display:none}

/* ---------- кнопки ---------- */
button,.btn{font:inherit;cursor:pointer;border:1px solid var(--line);background:var(--panel);
            border-radius:7px;padding:7px 13px;font-size:13px;color:var(--ink);
            display:inline-flex;align-items:center;gap:6px;text-decoration:none}
button:hover,.btn:hover{border-color:var(--line2);text-decoration:none}
.btn.pri,button.pri{background:var(--accent);border-color:var(--accent);color:#fff}
.btn.pri:hover,button.pri:hover{background:#2560d8}
/* Ссылка, за которой удаление. Не кнопка — она не главное действие, — но и
   не такая же синяя, как «скачать docx» рядом: цвет здесь и есть
   предупреждение. */
a.опасно{color:var(--late)}
a.опасно:hover{color:var(--late-ink)}
.btn.danger,button.danger{color:var(--late);border-color:#f0c9c9}
.btn.danger:hover,button.danger:hover{background:var(--late-soft)}
.btn.sm,button.sm{padding:4px 9px;font-size:12px}
button:disabled{opacity:.5;cursor:not-allowed}

/* ---------- поля ---------- */
label{display:block;font-size:12.5px;color:var(--muted);margin-bottom:3px}
label.inline{display:inline-flex;align-items:center;gap:6px;color:var(--ink);font-size:13px;margin:0}
input,select,textarea{font:inherit;font-size:13px;border:1px solid var(--line);border-radius:7px;
                      padding:6px 9px;background:var(--panel);color:var(--ink);width:100%;max-width:100%}
input[type=checkbox],input[type=radio]{width:auto;accent-color:var(--accent)}
input:focus,select:focus,textarea:focus{outline:2px solid var(--accent-soft);border-color:var(--accent)}
textarea{min-height:90px;resize:vertical}
fieldset{border:1px solid var(--line);border-radius:10px;padding:12px 14px;margin:0 0 14px;background:var(--panel)}
fieldset legend{font-size:11px;text-transform:uppercase;letter-spacing:.7px;color:var(--muted);padding:0 6px}
.field{margin-bottom:12px}
.form-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:12px 16px}
.form-actions{display:flex;gap:8px;align-items:center;margin-top:14px;flex-wrap:wrap}

/* Что подставила модель. Голубое — прочитано дословно, жёлтое — догадка,
   которую человек обязан проверить (§11a). */
.guess input,.guess textarea{background:var(--now-soft);border-color:var(--now)}
.exact input,.exact textarea{background:var(--accent-soft);border-color:var(--accent)}

/* ---------- карточки и таблицы ---------- */
.card,article{background:var(--panel);border:1px solid var(--line);border-radius:11px}
article{padding:16px 18px;margin:0 0 16px}
.pad{padding:16px 18px}
.stack{display:flex;flex-direction:column;gap:16px}

table{width:100%;border-collapse:collapse;background:var(--panel)}
table td,table th{padding:9px 11px;border-bottom:1px solid var(--line);text-align:left;font-size:13px;
                  vertical-align:top}
table th{font-size:11px;text-transform:uppercase;letter-spacing:.6px;color:var(--muted);font-weight:600}
table tr:last-child td{border-bottom:0}
table tr:hover td{background:var(--panel2)}
table.plain tr:hover td{background:transparent}
.tblcard{background:var(--panel);border:1px solid var(--line);border-radius:11px;overflow:hidden;margin-bottom:16px}
.tblcard table td:first-child,.tblcard table th:first-child{padding-left:16px}
.num{font-variant-numeric:tabular-nums;text-align:right;white-space:nowrap}

/* ---------- бейджи ---------- */
.b{display:inline-flex;align-items:center;gap:4px;font-size:11.5px;padding:2px 8px;flex:0 0 auto;
   border-radius:20px;white-space:nowrap;font-weight:500;background:var(--grid);color:var(--muted)}
.b.done{background:var(--done-soft);color:var(--done-ink)}
.b.now{background:var(--now-soft);color:var(--now-ink)}
.b.late{background:var(--late-soft);color:var(--late-ink)}
.b.wait{background:var(--wait-soft);color:var(--wait-ink)}
.b.idle{background:var(--grid);color:var(--muted)}
.b.edo{background:var(--accent-soft);color:var(--accent-ink)}
.b.accent{background:var(--accent-soft);color:var(--accent-ink)}
.b a{color:inherit}

/* ---------- сообщения на странице ---------- */
.alert{background:var(--now-soft);border:1px solid var(--now);border-radius:8px;padding:9px 12px;
       font-size:12.5px;color:var(--now-ink);margin-bottom:12px;display:flex;gap:8px}
.problems{background:var(--late-soft);border:1px solid var(--late);border-radius:8px;padding:9px 12px;
          font-size:12.5px;color:var(--late-ink);margin-bottom:12px}
.problems ul{margin:4px 0 0;padding-left:18px}
.problems li{color:inherit}
.note-ok{background:var(--done-soft);border:1px solid var(--done);border-radius:8px;padding:9px 12px;
         font-size:12.5px;color:var(--done-ink);margin-bottom:12px}
.checks{list-style:none;padding-left:0;margin:0;font-size:12.5px}
.checks li{padding:2px 0}
.check-ok::before{content:"✓ ";color:var(--done)}
.check-fail::before{content:"✗ ";color:var(--late)}
.check-fail{color:var(--late)}

/* Пустой экран - это тоже экран: он говорит, чего нет и что сделать. */
.empty{background:var(--panel);border:1px dashed var(--line);border-radius:11px;
       padding:26px 22px;text-align:center;color:var(--muted);font-size:13px;
       display:flex;flex-direction:column;align-items:center;gap:12px;margin-bottom:16px}

/* ---------- вкладки и фильтры ---------- */
.tabs{display:flex;gap:4px;background:var(--grid);padding:3px;border-radius:9px;width:fit-content;margin-bottom:16px}
.tabs a,.tabs button{border:0;background:transparent;padding:6px 14px;border-radius:6px;font-size:13px;
                     color:var(--muted);text-decoration:none;display:inline-flex;gap:6px;align-items:center}
.tabs a.on,.tabs button.on{background:var(--panel);color:var(--ink);box-shadow:0 1px 2px rgba(0,0,0,.08);font-weight:600}
.tabs .cnt{font-size:11px;color:var(--muted)}
.filters{display:flex;gap:7px;margin-bottom:12px;flex-wrap:wrap;align-items:center}
.chip{border:1px solid var(--line);background:var(--panel);border-radius:20px;padding:4px 12px;font-size:12.5px;
      color:var(--muted);text-decoration:none;display:inline-flex;gap:5px;align-items:center}
.chip:hover{border-color:var(--line2);text-decoration:none}
/* Выбранный фильтр-чип. В тёмной теме `--ink` светлый, и белый текст на нём
   пропадал, поэтому там плашка синяя. */
.chip.on{background:var(--ink);color:var(--panel);border-color:var(--ink)}
html[data-theme="dark"] .chip.on{background:var(--accent);color:#fff;border-color:var(--accent)}
.chip.on .cnt{color:#fff}
.chip .cnt{font-size:11px;color:var(--muted)}
.chip.personal{border-style:dashed}

/* ---------- канбан ---------- */
.kan{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(186px,1fr);gap:7px;overflow-x:auto;
     padding-bottom:12px;align-items:start}
.kcol{background:var(--grid);border-radius:10px;padding:8px;min-height:120px}
.kcol .ktop{display:flex;align-items:center;gap:6px;margin-bottom:3px}
.kcol .kn{width:19px;height:19px;flex:0 0 19px;border-radius:5px;background:var(--line2);color:var(--muted);
          display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}
.kcol h3{margin:0;font-size:11.5px;line-height:1.25;font-weight:600}
.kcol .meta{font-size:10.5px;color:var(--muted);margin:5px 0 8px;display:flex;justify-content:space-between;
            align-items:center;gap:4px}
.kcol .cc{background:var(--panel);border-radius:9px;padding:0 6px;font-weight:600;color:var(--muted)}
.kcol.hot{background:var(--late-soft)}
.kcol.hot .kn{background:var(--late);color:#fff}
.kcard{background:var(--panel);border:1px solid var(--line);border-radius:8px;padding:8px 9px;margin-bottom:6px;
       border-left:3px solid var(--idle);display:block;color:inherit;text-decoration:none}
.kcard:hover{box-shadow:0 2px 6px var(--тень);text-decoration:none}
.kcard.now{border-left-color:var(--now)}
.kcard.late{border-left-color:var(--late)}
.kcard.wait{border-left-color:var(--wait)}
.kcard.done{border-left-color:var(--done)}
.kcard .t{font-weight:600;font-size:12px;line-height:1.25;margin-bottom:1px}
.kcard .c{color:var(--muted);font-size:10.5px;margin-bottom:6px}
.kcard .r{display:flex;justify-content:space-between;align-items:flex-start;font-size:10.5px;
          color:var(--muted);gap:4px}
/* Название этапа переносится на вторую строку, а не обрезается многоточием:
   в колонке шириной полтора сантиметра «Тестирование и ...» не название. */
.kcard .r>span:first-child{min-width:0;overflow:hidden;display:-webkit-box;
                           -webkit-line-clamp:2;-webkit-box-orient:vertical;line-height:1.3}
.kcard .r>.dl{flex:0 0 auto;white-space:nowrap}
.kcard .r+.r{margin-top:3px}
/* Счётчик времени - своей строкой под бейджем. Раньше он стоял в одном ряду
   с ним и вылезал за карточку: бейдж не сжимается, а цифры не переносятся. */
.kcard .ход{display:flex;flex-wrap:wrap;align-items:center;gap:4px;margin-top:5px}
.kcard .счёт{font-size:10.5px;color:var(--muted);line-height:1.3}
/* Вехи: ТЗ утверждено, материалы получены, предоплата пришла. Показываются
   всегда - «ещё нет» здесь такой же ответ, как «да». */
.kcard .вехи{display:flex;flex-wrap:wrap;gap:3px 6px;margin-top:5px}
.kcard .веха{font-size:10px;color:var(--muted);white-space:nowrap;opacity:.65}
.kcard .веха.есть{color:var(--done-ink);opacity:1;font-weight:500}
.kcard .dl{font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums}
.kcard .dl.bad{color:var(--late)}
.kcard .wf{font-size:10.5px;color:#7c6bd8;margin-top:4px;line-height:1.3}
.kempty{font-size:10.5px;color:var(--muted);padding:4px 2px}

/* ---------- список проектов ---------- */
.rows{display:flex;flex-direction:column;gap:9px}
.row{background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:13px 16px;display:grid;
     grid-template-columns:230px 1fr 190px;gap:18px;align-items:center}
.row:hover{border-color:var(--accent)}
.row .nm{font-weight:600}
.row .org{color:var(--muted);font-size:12px}
.track{display:flex;gap:3px;align-items:center}
.seg{flex:1;height:22px;border-radius:4px;background:var(--grid);display:flex;align-items:center;
     justify-content:center;font-size:10.5px;color:var(--muted)}
.seg.done{background:var(--done);color:#fff}
.seg.now{background:var(--now);color:#fff}
.seg.late{background:var(--late);color:#fff}
.seg.wait{background:var(--wait);color:#fff}
.tracklbl{display:flex;justify-content:space-between;font-size:10.5px;color:var(--muted);margin-top:4px}
.right{text-align:right}
.right .d{font-weight:600;font-variant-numeric:tabular-nums}
.right .l{font-size:11.5px;color:var(--muted)}

/* ---------- карточка проекта ---------- */
.grid2{display:grid;grid-template-columns:1fr 300px;gap:14px;align-items:start}
/* Последняя колонка фиксированной ширины, а не `auto`. С `auto` она равнялась
   ширине блока кнопок в строке и нулю в шапке - от этого подписи «план от
   оплаты, прогноз, факт» стояли на 130 пикселей правее самих дат. */
.stage{display:grid;grid-template-columns:26px 1fr 84px 84px 116px 116px 113px;gap:7px;align-items:center;
       padding:10px 0;border-bottom:1px solid var(--line);font-size:13px}
.stage:last-child{border:0}
.stage .n{width:22px;height:22px;border-radius:50%;background:var(--grid);color:var(--muted);display:flex;
          align-items:center;justify-content:center;font-size:11px;font-weight:600}
.stage.done .n{background:var(--done);color:#fff}
.stage.now .n{background:var(--now);color:#fff}
.stage.late .n{background:var(--late);color:#fff}
.stage .tsk{font-size:11.5px;color:var(--muted);margin-top:2px}
.stage .dcol{font-variant-numeric:tabular-nums;font-size:12.5px;text-align:right}
.stage .dcol.plan{color:var(--muted)}
.stage .dcol.shift{color:var(--late)}
/* Редлайн прошёл, а этап не закрыт: внутренний срок сгорел, обещанный ещё нет. */
.stage .dcol.горит{color:var(--now-ink);font-weight:500}
.stage.sub{padding-left:26px;font-size:12.5px}
.stage.sub .n{width:22px;height:22px;font-size:9.5px;letter-spacing:-.02em}
.stage .имя{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.stage .over{color:var(--late)}
/* Шапка колонок дат. Раньше подпись «план от оплаты, прогноз, факт» стояла
   одной строкой справа от заголовка и ни над какой колонкой не была. */
.stage.шапка{padding:6px 0;border-bottom:1px solid var(--line2);
             font-size:10.5px;text-transform:uppercase;letter-spacing:.06em;
             color:var(--muted);font-weight:600}
.stage.шапка .dcol{font-size:10.5px}

/* Действия на строке этапа - иконками, а не строчками «Поправить этап 3».
   Панель правки открывается поверх списка: этапов десяток, и раскрывать её
   в поток значит каждый раз ронять всё, что ниже, на пол-экрана вниз. */
/* Фактические даты - поля прямо в строке, а не текст. При заведении проекта
   задним числом их правят у всех этапов подряд, и путь через панель за
   карандашом означал бы по два лишних клика на каждый. */
.дата{display:contents}
.дата input{width:100%;padding:3px 5px;font-size:11.5px;border-radius:6px;
            font-variant-numeric:tabular-nums}
.дата input:not(:placeholder-shown),.дата input:valid{color:var(--ink)}

/* Дата по-русски: видимое текстовое поле, кнопка календаря и спрятанное
   родное `type=date`, из которого значение и уходит на сервер. */
.дата-поле{position:relative;display:inline-flex;align-items:center;width:100%}
.дата-поле .дата-текст{width:100%;padding-right:26px;font-variant-numeric:tabular-nums}
.дата-поле .дата-текст.плохо{border-color:var(--late);color:var(--late)}
.дата-поле .дата-пикер{position:absolute;right:2px;width:22px;height:22px;padding:0;
                       border:0;background:transparent;font-size:12px;opacity:.55;
                       display:inline-flex;align-items:center;justify-content:center}
.дата-поле .дата-пикер:hover{opacity:1;background:transparent}
.дата-поле .дата-скрытая{position:absolute;left:0;bottom:0;width:1px;height:1px;
                         padding:0;border:0;opacity:0;pointer-events:none}
.дата input.дата-текст{padding:3px 20px 3px 5px;font-size:11.5px}
.дата .дата-пикер{right:0;width:18px}
.поле-подпись{font-size:11px;color:var(--muted);line-height:1.35;margin-top:4px}

.ктоделает{display:flex;align-items:center;gap:8px;padding:6px 0;
           border-bottom:1px solid var(--line);font-size:13px;margin:0}
.ктоделает select{width:auto;margin-left:auto;padding:3px 6px;font-size:12px}

.дейст{display:flex;gap:3px;align-items:center}
.дейст form{margin:0}
.знч{width:26px;height:26px;padding:0;display:inline-flex;align-items:center;
     justify-content:center;font-size:13px;line-height:1;border-radius:7px;
     border:1px solid var(--line);background:var(--panel);color:var(--ink);
     cursor:pointer;font:inherit;font-size:13px}
.знч:hover{border-color:var(--line2);background:var(--panel2)}
.знч.ок{color:var(--done-ink)}
.знч.опасно{color:var(--late-ink)}
details.правка{position:relative}
details.правка>summary{list-style:none}
details.правка>summary::-webkit-details-marker{display:none}
details.правка[open]>summary{background:var(--accent-soft);border-color:var(--accent)}
.панель{position:absolute;right:0;top:calc(100% + 6px);z-index:60;
        width:min(620px,86vw);max-height:min(70vh,620px);overflow:auto;
        background:var(--panel);border:1px solid var(--line2);
        border-radius:11px;box-shadow:0 10px 30px var(--тень-сильная);padding:12px 14px;
        text-align:left;font-weight:400}
.панель.слева{right:auto;left:0}
.панель .пзаг{font-size:10.5px;text-transform:uppercase;letter-spacing:.06em;
              color:var(--muted);font-weight:600;margin:12px 0 6px}
.панель .пзаг:first-child{margin-top:0}
.панель form+.пзаг{border-top:1px solid var(--line);padding-top:12px}
.панель .form-actions{margin-top:8px}

/* Действия над всем списком этапов - одной строкой, а не столбиком раскрывашек */
.этапы-действия{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px;
                padding-top:12px;border-top:1px solid var(--line)}
.этапы-действия>details{position:relative}

/* Счётчик времени: наше, ожидание клиента, за кем ход */
.clock{display:flex;gap:8px;margin:10px 0 10px;flex-wrap:wrap}
.clock .c{flex:1 1 130px;padding:9px 11px;border:1px solid var(--line);border-radius:9px;background:var(--grid)}
.clock .c.on{border-color:var(--now);background:var(--now-soft)}
.clock .c.on.wait,.clock .c.ход.wait{border-color:var(--wait-ink);background:var(--wait-soft)}
.clock .c .d{font-size:19px;font-weight:600;font-variant-numeric:tabular-nums;line-height:1.2}
.clock .c .d .ед{font-size:12px;font-weight:500;color:var(--muted)}
.clock .c .l{font-size:11.5px;color:var(--muted);margin-top:1px}
.clock .c .ч{font-size:11px;color:var(--muted);opacity:.75;margin-top:3px}
.clock .c.ход .d{font-size:14px;line-height:1.35}
.kv{display:flex;justify-content:space-between;gap:12px;padding:6px 0;border-bottom:1px solid var(--line);font-size:13px}
.kv:last-child{border:0}
.kv .k{color:var(--muted)}
.docline{display:flex;justify-content:space-between;align-items:center;padding:8px 0;
         border-bottom:1px solid var(--line);gap:8px}
.docline:last-child{border:0}
.docline .dn{font-size:13px}
.docline .dm{font-size:11.5px;color:var(--muted)}
.payline{display:flex;justify-content:space-between;align-items:center;padding:8px 0;
         border-bottom:1px solid var(--line);font-size:12.5px;gap:10px}
.payline:last-child{border:0}
.bar{height:6px;border-radius:4px;background:var(--grid);overflow:hidden;margin:8px 0 4px}
.bar i{display:block;height:100%;background:var(--done)}
.legend{display:flex;gap:14px;flex-wrap:wrap;font-size:11.5px;color:var(--muted);margin:10px 0 0}
.legend span{display:flex;align-items:center;gap:5px}
.sw{width:10px;height:10px;border-radius:3px;display:inline-block}

/* ---------- редактор этапов ---------- */
.stged{display:grid;grid-template-columns:24px 1fr 74px 92px 90px 28px;gap:9px;align-items:center;
       padding:7px 0;border-bottom:1px solid var(--line);font-size:12.5px}
.stged:last-child{border:0}
.stged input,.stged select{padding:4px 7px;font-size:12.5px}

/* ---------- меню действий ---------- */
.меню{position:relative}
.меню>summary{list-style:none;cursor:pointer}
.меню>summary::-webkit-details-marker{display:none}
.меню[open]>summary{border-color:var(--line2);background:var(--panel2)}
.выпадение{position:absolute;right:0;top:calc(100% + 6px);z-index:50;min-width:230px;
           background:var(--panel);border:1px solid var(--line);border-radius:10px;
           box-shadow:0 8px 24px var(--тень-сильная);padding:5px;display:flex;
           flex-direction:column}
.выпадение a,.выпадение button{display:block;width:100%;text-align:left;border:0;
                               background:transparent;padding:8px 11px;border-radius:7px;
                               font-size:13px;color:var(--ink);text-decoration:none}
.выпадение a:hover,.выпадение button:hover{background:var(--accent-soft);text-decoration:none}
.выпадение form{margin:0}

/* ---------- ход обработки ---------- */
.шаги{display:flex;gap:6px;flex-wrap:wrap;margin:8px 0 6px}
.шаг{font-size:11.5px;padding:2px 9px;border-radius:20px;background:var(--panel);
     border:1px solid var(--now);color:var(--now-ink)}
.шаг.сделан{background:var(--done-soft);border-color:var(--done);color:var(--done-ink)}
.шаг.сделан:before{content:"✓ "}
.шаг.идёт{background:var(--now);border-color:var(--now);color:#fff;font-weight:600}
.шаг.идёт:after{content:" …"}

/* ---------- всплывающие сообщения ---------- */
.тосты{position:fixed;right:18px;bottom:18px;z-index:60;display:flex;flex-direction:column;
       gap:8px;max-width:min(420px,calc(100vw - 36px))}
.тост{background:var(--panel);border:1px solid var(--line);border-left-width:3px;
      border-radius:10px;padding:11px 14px;font-size:12.5px;line-height:1.45;
      box-shadow:0 8px 24px var(--тень-сильная);cursor:pointer;
      animation:тост-въезд .18s ease-out}
.тост.хорошо{border-left-color:var(--done);color:var(--done-ink)}
.тост.плохо{border-left-color:var(--late);color:var(--late-ink)}
@keyframes тост-въезд{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.тост{animation:none}}

/* ---------- заливка записи на расшифровку ----------
   Панель висит поверх страницы и переживает переход по разделам: файл
   уходит отдельным запросом, и человеку надо видеть, что тот жив. */
.загрузка{position:fixed;right:18px;bottom:18px;z-index:61;width:min(320px,calc(100vw - 36px));
          background:var(--panel);border:1px solid var(--line);border-radius:10px;
          padding:11px 14px;box-shadow:0 8px 24px var(--тень-сильная);
          font-size:12.5px;line-height:1.45}
.загрузка .что{font-weight:600}
.загрузка .подсказка{color:var(--muted);font-size:11px;margin-top:6px}
.загрузка .полоса{height:5px;border-radius:3px;background:var(--line);margin-top:8px;overflow:hidden}
.загрузка .полоса i{display:block;height:100%;background:var(--accent);
                    transition:width .2s linear}
.загрузка .полоса.неизвестно i{animation:заливка-ход 1.1s ease-in-out infinite;opacity:.6}
@keyframes заливка-ход{0%{opacity:.25}50%{opacity:.7}100%{opacity:.25}}
@media (prefers-reduced-motion:reduce){.загрузка .полоса.неизвестно i{animation:none}}

/* Перенос задач из трекера: свёрнут, потому что нужен раз в жизни.
   Вид - общий для раскрывашек (класс `раскрыть`), здесь только отступ. */
/* «Выполненные» внизу бэклога. Свёрнуто браузером, а не свёртком групп:
   группы по умолчанию развёрнуты, а двадцать закрытых строк под списком дел
   нужны редко - их открывают с вопросом «куда делась задача, которую я
   закрыл». Выглядит как заголовок группы: это такой же список, только
   закрытых. */
.выполненные>summary{display:flex;align-items:center;gap:7px;cursor:pointer;
                     list-style:none;font-size:11px;font-weight:600;
                     text-transform:uppercase;letter-spacing:.06em;
                     color:var(--muted);margin:20px 3px 7px}
.выполненные>summary::-webkit-details-marker{display:none}
.выполненные>summary::before{content:"▸";font-size:9px;opacity:.75}
.выполненные[open]>summary::before{content:"▾"}
.выполненные>summary:hover{color:var(--ink)}
.выполненные>summary span{font-weight:600;letter-spacing:0;text-transform:none}

.перенос-задач{margin-top:18px}

/* ---------- плитки настроек ----------
   Восемь пунктов меню подряд не читались: то, чем пользуешься каждый день,
   тонуло в том, что открывают раз в месяц. Здесь у каждого раздела есть
   подпись, зачем он нужен, - в сайдбаре её было негде взять. */
.плитки{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:10px}
.плитка{display:flex;flex-direction:column;gap:4px;background:var(--panel);
        border:1px solid var(--line);border-radius:11px;padding:14px 16px;
        color:var(--ink);text-decoration:none}
.плитка:hover{border-color:var(--accent);box-shadow:0 2px 10px var(--тень);
              text-decoration:none}
.плитка strong{font-size:13.5px}
.плитка .muted{font-size:12px;line-height:1.45}

/* ---------- поиск ---------- */
.поиск{position:relative;padding:0 14px 4px}
.поиск input{background:#1d242d;border-color:#2b333d;color:#c9d1d9;font-size:12.5px;
             padding:6px 9px;border-radius:7px}
.поиск input::placeholder{color:#6b7784}
.поиск input:focus{outline:none;border-color:var(--accent);background:#222b35}
/* Шире сайдбара: в 180 пикселей название компании переносится по слогам,
   и прочитать выдачу нельзя. */
.найдено{position:absolute;left:14px;right:auto;width:min(420px,calc(100vw - 40px));
         top:100%;z-index:40;background:var(--panel);
         border:1px solid var(--line);border-radius:10px;box-shadow:0 8px 24px var(--тень-сильная);
         overflow:hidden;max-height:70vh;overflow-y:auto}
.найдено .строка{display:flex;gap:10px;align-items:baseline;padding:9px 12px;color:var(--ink);
                 border-bottom:1px solid var(--line);text-decoration:none}
.найдено .строка:last-child{border-bottom:0}
.найдено .строка:hover{background:var(--accent-soft);text-decoration:none}
.найдено .вид{font-size:9.5px;text-transform:uppercase;letter-spacing:.6px;color:var(--muted);
              flex:0 0 62px}
.найдено .имя{display:block;font-size:12.5px;line-height:1.3}
.найдено .подпись{display:block;font-size:11px;color:var(--muted);margin-top:1px}
.найдено .пусто{padding:10px 12px;font-size:12.5px;color:var(--muted)}

/* ---------- производственный календарь ---------- */
.года{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px}
.мес-имя{font-size:11.5px;font-weight:600;color:var(--muted);margin-bottom:3px;text-transform:capitalize}
table.мини{background:transparent}
table.мини th{padding:2px 0;font-size:9.5px;text-align:center;letter-spacing:0}
table.мини td{padding:3px 0;border:0;text-align:center;font-size:11.5px;
              font-variant-numeric:tabular-nums;border-radius:4px}
table.мини tr:hover td{background:transparent}
table.мини td.выходной{background:var(--grid);color:var(--muted)}
table.мини td.перенос{background:var(--now-soft);color:var(--now-ink);font-weight:600;
                      box-shadow:inset 0 0 0 1px var(--now)}
table.мини td.нет{background:var(--late-soft);color:var(--late-ink)}
table.мини td.сегодня{box-shadow:inset 0 0 0 2px var(--accent);font-weight:700}

/* ---------- бриф ---------- */
.q{display:grid;grid-template-columns:56px 1fr 340px;gap:12px;padding:11px 0;
   border-bottom:1px solid var(--line);font-size:13px;align-items:start}
.q:last-child{border:0}
.q .code{font-weight:600;color:var(--muted);font-size:12px}
.q .code .cr{color:var(--late);font-weight:700}
.q .ex{font-size:11.5px;color:var(--muted);margin-top:3px;font-style:italic}
.q .ans{font-size:12.5px;line-height:1.45}
.q .ans.pre{background:var(--accent-soft);border-left:2px solid var(--accent);padding:6px 9px;
            border-radius:0 6px 6px 0}
.q .ans.guess{background:var(--now-soft);border-left-color:var(--now)}
.q .ans.empty{color:var(--muted)}
/* Незаполненный ответ в брифе: сама заглушка и есть кнопка «вписать». */
details.вписать>summary{display:block;list-style:none;cursor:pointer;
  border:1px dashed #dfe3e8;border-radius:8px;padding:10px 11px;
  color:#9aa1aa;font-size:12.5px}
details.вписать>summary::-webkit-details-marker{display:none}
details.вписать>summary:hover{border-color:var(--accent);color:var(--accent)}
/* Раскрылась - заглушка не нужна: в форме уже есть поле для ответа. */
details.вписать[open]>summary{display:none}
.q .src{font-size:11px;color:#2f6fed;margin-top:4px;line-height:1.4}
.q .src.g{color:var(--now-ink)}
.q form{margin:6px 0 0}
.q textarea{font-size:12.5px;padding:5px 8px;min-height:52px}
.q .qacts{display:flex;gap:6px;align-items:center;margin-top:5px;flex-wrap:wrap}
.sec{background:var(--grid);border-radius:8px;padding:8px 12px;margin:14px 0 4px;font-size:12.5px;
     font-weight:600;display:flex;justify-content:space-between;align-items:center;gap:10px}
.sec .wa{font-weight:400;font-size:11.5px;color:var(--muted)}
.mdbox{background:#1e242c;color:#c9d1d9;border-radius:9px;padding:13px 15px;
       font:12px/1.6 ui-monospace,SFMono-Regular,Menlo,monospace;white-space:pre;
       overflow:auto;max-height:340px}

/* ---------- сообщения клиенту ---------- */
.msgbox{background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:15px 17px;font-size:13px;
        line-height:1.6;white-space:pre-wrap}
.msgbox .v{background:var(--done-soft);color:var(--done-ink);border-radius:4px;padding:0 3px;font-weight:600}
.tpl{display:block;padding:9px 12px;border-radius:8px;font-size:12.5px;cursor:pointer;
     border:1px solid transparent;color:inherit;text-decoration:none}
.tpl:hover{background:var(--panel2);text-decoration:none}
.tpl.on{background:var(--accent-soft);border-color:var(--accent);font-weight:600}
.tpl small{display:block;color:var(--muted);font-weight:400;font-size:11px;margin-top:1px}

/* ---------- правила уведомлений ---------- */
.rules{display:flex;flex-direction:column;gap:8px}
.rule{display:grid;grid-template-columns:1fr 150px 130px 90px;gap:12px;align-items:center;background:var(--panel);
      border:1px solid var(--line);border-radius:9px;padding:11px 14px;font-size:13px}
.feed{display:flex;gap:10px;padding:9px 0;border-bottom:1px solid var(--line);font-size:12.5px}
.feed:last-child{border:0}
.feed .ic{width:24px;height:24px;flex:0 0 24px;border-radius:6px;display:flex;align-items:center;
          justify-content:center;font-size:12px;background:var(--grid)}

/* Быстрый ввод пункта повестки, правка строки и кнопка даты в строке списка:
   этими классами пользуются планёрки, учётки, брифы и реестр счетов. Экран
   задач с 20.08.2026 верстается своими классами (ниже), но выносить эти
   правила отсюда некуда - они общие. */
.qadd{display:flex;gap:8px;background:var(--panel);border:1px solid var(--line);
      border-radius:10px;padding:8px 10px}
.qadd input{border:0;padding:4px 5px;font-size:14px}
.qadd input:focus{outline:0}
.rowform{display:flex;gap:5px;align-items:center}
.rowform input[type=date]{padding:3px 6px;font-size:12px;width:auto}
.rowform button{padding:3px 9px;font-size:12px}
.tedit{margin-top:5px}
.tedit form{display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin-top:6px}
.tedit input,.tedit select,.tedit button{width:auto;padding:4px 8px;font-size:12.5px}
.tedit input[type=text]{min-width:15rem}
/* Раскрытая правка - панель, а не поля, высыпавшиеся в строку списка. */
.tedit[open]{background:var(--panel2);border:1px solid var(--line);border-radius:9px;
             padding:8px 10px;margin-top:7px}
.tedit[open] form+form{border-top:1px dashed var(--line);padding-top:8px;margin-top:8px}
.tedit[open] form+form+a{display:inline-block;margin-top:8px}

/* ---------- задачи ----------

   Экран переработан 20.08.2026 по замечаниям Алексея. Три вещи, которые здесь
   держатся:

   1. **Узкая колонка.** Список дел, растянутый на полтора экрана, читается
      плохо: от кружка до кнопок глаз идёт через пустоту. Расписание -
      исключение, ему нужны семь колонок по часам.
   2. **Строка спокойная и высокая.** Приоритет - цветом кружка, а не меткой;
      метка даты - только когда добавляет что-то к тому, где строка и так
      лежит; метка из выгрузки трекера не показывается вовсе.
   3. **Действия - настоящие кнопки**, а не мелкий серый текст: «Сегодня»,
      «Дата», приоритет и крестик. Крестик убирает в корзину. */

.задачи{max-width:880px;margin:0 auto}
.задачи.широко{max-width:1400px}
.зшапка{display:flex;align-items:center;gap:10px;margin-bottom:14px;flex-wrap:wrap}
.зшапка h1{margin:0}
.растяжка{flex:1}

/* Верх экрана - прилипший: быстрый ввод, вкладки и фильтры видно из любого
   места списка. При прокрутке сжимается: подсказка по синтаксису прячется,
   отступы уменьшаются. Класс вешает `tasks.js` по положению прокрутки. */
.зверх{position:sticky;top:0;z-index:20;background:var(--bg);
       padding:2px 0 8px;margin-bottom:2px}
.зверх:after{content:"";position:absolute;left:0;right:0;bottom:0;height:10px;
             pointer-events:none;background:linear-gradient(var(--bg),transparent)}
.зверх.сжата .подсказка{display:none}
.зверх.сжата .ввод{padding:5px 12px}
.зверх.сжата .tabs.широкие a{padding:6px 12px}
.зверх.сжата{box-shadow:0 6px 14px -12px rgba(10,15,25,.5)}
/* Без этого экран задач «бешено дёргался» (10.10.2026): верх сжимается,
   браузер ради «якоря прокрутки» сдвигает страницу на ту же высоту вверх,
   прокрутка падает к нулю, верх расправляется, браузер сдвигает обратно - и
   так по кругу. Высоту верха мы меняем сами и знаем об этом, подстраховка
   браузера здесь только вредит. */
html:has(.зверх){overflow-anchor:none}

/* быстрый ввод */
.ввод{display:flex;gap:8px;align-items:center;background:var(--panel);
      border:1px solid var(--line);border-radius:11px;padding:8px 12px;
      box-shadow:0 1px 2px rgba(20,30,50,.04)}
.ввод:focus-within{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.ввод .плюс{color:var(--muted);font-size:17px;line-height:1}
.ввод input[type=text]{flex:1;border:0;padding:5px 2px;font-size:15px;background:transparent}
.ввод input[type=text]:focus{outline:0}
/* Списки направления и исполнителя - по содержимому, а не в пол-строки.
   Восемь с половиной рем они занимали всегда, даже под словом «Мои». */
.ввод select{width:auto;min-width:5.5rem;max-width:9rem;font-size:12.5px;padding:5px 8px}
/* Поле срока в строке ввода: уже остальных, в нём восемь цифр. */
.ввод .дата-поле{width:7.6rem;flex:0 0 auto}
.ввод .дата-поле .дата-текст{font-size:12.5px;padding:5px 22px 5px 8px}
/* Строка «Новое событие» в расписании: там заводят не задачи, и поле ввода
   было бы обманом. Одна кнопка, поэтому и строка ниже. */
.ввод.узко{padding:4px 12px}
.строка-кнопка{border:0;background:transparent;padding:5px 2px;font:inherit;
               font-size:14px;color:var(--muted);text-align:left;flex:1}
.строка-кнопка:hover{color:var(--accent);border:0}
.ввод .муть{font-size:11.5px;color:var(--muted)}

.подсказка{font-size:11.5px;color:var(--muted);margin:7px 2px 14px;line-height:1.5}
.подсказка b{color:var(--accent);font-weight:600}

/* вкладки пошире: их четыре, и они главный переключатель экрана */
.tabs.широкие{width:100%;margin-bottom:10px}
.tabs.широкие a{flex:1;justify-content:center;padding:8px 12px;font-size:13.5px}
.tabs.мелкие{margin:0}
.tabs.мелкие a{padding:4px 10px;font-size:12px}

/* фильтры одной строкой */
.отбор{display:flex;gap:7px;align-items:center;flex-wrap:wrap;margin-bottom:14px}
.отбор select{width:auto;max-width:14rem;font-size:12.5px;padding:5px 9px;
              border-radius:20px;color:var(--muted);background:var(--panel)}
.отбор select.выбран{color:var(--ink);border-color:var(--accent);background:var(--accent-soft)}
.отбор .сброс{font-size:12.5px;color:var(--accent);padding:0 4px}

/* группы и строки */
.згруппа{display:flex;align-items:center;gap:8px;font-size:11px;font-weight:600;
         text-transform:uppercase;letter-spacing:.06em;color:var(--muted);
         margin:20px 3px 7px}
.згруппа span{font-weight:600;letter-spacing:0}
.згруппа.поздно{color:var(--late)}
/* Поручение, на которое не ответили. Выделено цветом ожидания, а не тревоги:
   это не просрочка, а вопрос, оставшийся без ответа. */
.згруппа.ждёт-ответа{color:var(--wait-ink)}
.згруппа.ждёт-ответа .згруппа-действие{color:var(--muted);font-weight:400}
.згруппа-действие{margin:0 0 0 auto;text-transform:none;letter-spacing:0}
/* Заголовок группы - он же переключатель: список сворачивается и
   разворачивается по ходу дня. Утром смотрят, что идёт дальше, к обеду это
   только мешает видеть сегодняшнее. Свёрнутость помнит браузер. */
.згруппа .сверток{display:inline-flex;align-items:center;gap:7px;background:none;border:0;
                  padding:0;font:inherit;color:inherit;text-transform:inherit;
                  letter-spacing:inherit;width:auto}
.згруппа .сверток:hover{color:var(--ink)}
.згруппа.поздно .сверток:hover{color:var(--late-ink)}
.згруппа .стрелка{display:inline-block;font-style:normal;font-size:9px;line-height:1;
                  opacity:.75;transition:transform .12s ease}
.згруппа.свёрнута .стрелка{transform:rotate(-90deg)}
.зсписок{background:var(--panel);border:1px solid var(--line);border-radius:11px;
         margin-bottom:6px}
.зпусто{padding:22px 16px;text-align:center;color:var(--muted);font-size:13px}

.зрок{display:flex;align-items:flex-start;gap:12px;padding:13px 14px;
      border-top:1px solid var(--line)}
.зрок:first-child{border-top:0}
.зрок:hover{background:var(--panel2)}
.зрок form{margin:0}
.зрок.закрыта .имя{color:var(--muted);text-decoration:line-through}

/* кружок с цветом приоритета: сам приоритет отдельной меткой больше не пишем */
.круг{width:19px;height:19px;flex:0 0 19px;margin-top:1px;border-radius:50%;
      border:1.8px solid var(--idle);padding:0;background:transparent}
.круг.p1{border-color:var(--late)}
.круг.p2{border-color:var(--now)}
.круг.p3{border-color:var(--синий)}
button.круг:hover{background:var(--accent-soft);border-color:var(--accent)}
.круг.сделана{background:var(--done);border-color:var(--done);position:relative}
.круг.сделана::after{content:"";position:absolute;left:6px;top:2.5px;width:4px;height:8px;
                     border:solid #fff;border-width:0 2px 2px 0;transform:rotate(43deg)}
.круг.чужая{opacity:.45;cursor:not-allowed}

.зрок .суть{flex:1;min-width:0}
.зрок .имя{display:block;width:100%;text-align:left;border:0;background:transparent;
           padding:0;font:inherit;font-size:14px;line-height:1.35;color:var(--ink);
           cursor:pointer;word-wrap:break-word}
.зрок .имя:hover{color:var(--accent);text-decoration:none}
.метки{display:flex;gap:5px;flex-wrap:wrap;margin-top:5px;align-items:center}
.метка{display:inline-flex;align-items:center;gap:4px;font:inherit;font-size:11.5px;
       line-height:1.5;padding:1px 8px;border-radius:20px;white-space:nowrap;
       border:1px solid var(--line);background:var(--panel2);color:var(--muted)}
button.метка{cursor:pointer}
button.метка:hover{border-color:var(--accent);color:var(--accent)}
.метка.поздно{color:var(--late);background:var(--late-soft);border-color:transparent}
/* «Ждёт вас»: задача Норы стоит без ответа. Плашкой цвета, а не бледной
   меткой: по строке должно быть видно сразу, что ход за вами. */
.метка.ждёт{color:#fff;background:var(--late);border-color:var(--late);font-weight:600}
.метка.сегодня{color:var(--accent);background:var(--accent-soft);border-color:transparent}
.метка.час{color:var(--wait-ink);background:var(--wait-soft);border-color:transparent;
           font-variant-numeric:tabular-nums}
.метка.связь{color:var(--ink)}
.метка.связь:hover{border-color:var(--accent);text-decoration:none}
.метка.личное{border-style:dashed}
.метка.ждёт{color:var(--now-ink);background:var(--now-soft);border-color:transparent}

.зрок .кнопки{display:flex;gap:4px;align-items:center;flex:none;opacity:.5;
              transition:opacity .12s}
.зрок:hover .кнопки,.зрок:focus-within .кнопки{opacity:1}
.дейст{border:1px solid var(--line);background:var(--panel);color:var(--muted);
       font:inherit;font-size:11.5px;padding:3px 10px;border-radius:7px;white-space:nowrap}
.дейст:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}
.значок{border:0;background:transparent;color:var(--muted);width:26px;height:26px;
        border-radius:7px;padding:0;display:flex;align-items:center;justify-content:center;
        font-size:13px}
.значок:hover{background:var(--line);color:var(--ink);border:0}
.значок.p1{color:var(--late)} .значок.p2{color:var(--now)} .значок.p3{color:var(--синий)}
.значок.убрать:hover{color:var(--late);background:var(--late-soft)}

/* Ответ на поручение: две кнопки и причина - в одну строку под задачей. */
.ответ{display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin-top:7px}
.ответ input[type=text]{width:auto;min-width:13rem;padding:4px 8px;font-size:12.5px}

/* Чужая загрузка, которой не видно: только число, без названий. */
.скрытое{font-size:12px;color:var(--muted);margin:10px 3px 0;line-height:1.5}

/* ---------- выпадающее меню строки ---------- */
.меню-слой:empty{display:none}
.меню-окно{position:fixed;z-index:80;min-width:220px;max-height:70vh;overflow:auto;
           background:var(--panel);border:1px solid var(--line);border-radius:10px;
           box-shadow:0 10px 30px var(--тень-сильная);padding:5px}
.меню-окно form{margin:0}
.меню-окно button{display:flex;width:100%;align-items:center;gap:8px;border:0;
                  background:transparent;padding:7px 10px;border-radius:7px;
                  font-size:13px;color:var(--ink);text-align:left}
.меню-окно button:hover{background:var(--accent-soft)}
.меню-окно button.pri{background:var(--accent);color:#fff;justify-content:center;margin-top:6px}
.меню-окно button span{margin-left:auto;font-size:11.5px;color:var(--muted)}
.меню-окно button small{color:var(--muted);font-size:11px}
.меню-окно .меню-ссылка{display:block;padding:7px 10px;border-radius:7px;font-size:13px}
.меню-окно .меню-ссылка:hover{background:var(--accent-soft);text-decoration:none}
.меню-окно .меню-подпись{font-size:10.5px;text-transform:uppercase;letter-spacing:.06em;
                         color:var(--muted);padding:6px 10px 3px}
.меню-окно .меню-черта{height:1px;background:var(--line);margin:4px 2px}
.меню-окно .меню-подсказка{font-size:11px;color:var(--muted);padding:6px 10px 3px;line-height:1.4}
.меню-окно input{font-size:13px;padding:6px 9px}
.точка{width:9px;height:9px;border-radius:50%;flex:none;background:var(--idle);display:inline-block}
.точка.p1{background:var(--late)} .точка.p2{background:var(--now)} .точка.p3{background:var(--синий)}
.точка.готово{background:var(--done);opacity:.5}
.точка.поздно{background:var(--late)}

/* ---------- карточка задачи ---------- */
.окно{border:0;border-radius:14px;padding:0;max-width:min(680px,calc(100vw - 32px));
      width:100%;background:var(--panel);color:var(--ink);
      box-shadow:0 24px 60px var(--тень-сильная)}
.окно::backdrop{background:rgba(15,20,30,.35)}
.окно #карточка-тело{padding:20px 22px}
.карточка-шапка{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}
.карточка-шапка h2{margin:2px 0 0;font-size:17px;line-height:1.3}
.карточка-путь{font-size:11.5px;color:var(--muted)}
.карточка-форма{margin-top:14px}
.карточка-форма label{margin-bottom:10px}
.карточка-поля{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));
               gap:2px 14px;margin-top:4px}
.карточка-блок{margin-top:16px;padding-top:14px;border-top:1px solid var(--line)}
.слот-строка{display:flex;align-items:center;gap:10px;font-size:12.5px;
             font-variant-numeric:tabular-nums;padding:3px 0}
.слот-строка form{margin:0}
.слот-форма{display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin-top:8px}
.слот-форма input,.слот-форма select,.слот-форма button{width:auto;font-size:12.5px;padding:5px 8px}
.карточка-низ{display:flex;gap:16px;align-items:center;margin-top:14px;padding-top:12px;
              border-top:1px solid var(--line)}
.карточка-низ form{margin:0}
.ссылкой.опасно{color:var(--late)}

/* ---------- календарь планов ---------- */
.кал-шапка{display:flex;align-items:center;gap:8px;margin-bottom:12px;flex-wrap:wrap}
.кал-имя{font-size:15px;text-transform:capitalize}
.месяц{background:var(--panel);border:1px solid var(--line);border-radius:11px;padding:10px}
.месяц-дни,.месяц-строка{display:grid;grid-template-columns:repeat(7,1fr);gap:4px}
.месяц-дни div{text-align:center;font-size:10.5px;color:var(--muted);padding-bottom:4px}
.месяц-строка+.месяц-строка{margin-top:4px}
.день{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;
      height:clamp(48px,7vw,62px);border-radius:9px;border:1px solid transparent;
      color:var(--ink);font-size:14px;text-decoration:none}
.день:hover{background:var(--panel2);border-color:var(--line);text-decoration:none}
.день.чужой{color:var(--muted);opacity:.45}
.день.сегодня{background:var(--accent-soft)}
.день.сегодня .число{color:var(--accent);font-weight:700}
.день.выбран{border-color:var(--accent);background:var(--accent-soft)}
.точки{display:flex;gap:3px;height:7px;align-items:center}

.кал-неделя{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:6px;
            align-items:start}
.кал-колонка{background:var(--grid);border-radius:10px;padding:7px;min-height:120px}
.кал-колонка.сегодня{background:var(--accent-soft)}
.кал-заголовок{display:flex;justify-content:space-between;align-items:center;gap:4px;
               font-size:11px;color:var(--muted);margin-bottom:6px}
.кал-заголовок a{color:inherit}
.кал-задача{display:block;width:100%;text-align:left;background:var(--panel);
            border:1px solid var(--line);border-left:3px solid var(--idle);
            border-radius:8px;padding:6px 8px;margin-bottom:5px;font-size:11.5px;
            line-height:1.3;color:var(--ink)}
.кал-задача:hover{box-shadow:0 2px 6px var(--тень)}
.кал-задача.p1{border-left-color:var(--late)}
.кал-задача.p2{border-left-color:var(--now)}
.кал-задача.p3{border-left-color:var(--синий)}
.кал-задача.готово{color:var(--muted);text-decoration:line-through}
.кал-пусто{font-size:11px;color:var(--muted);padding:2px}

/* ---------- спрятанное за кнопкой ----------

   Раньше форма пряталась за мелким серым текстом: «⋯ правка» у задачи,
   «+ Платёж» и «Зафиксировать поступление» на карточке проекта. За
   кликабельное это не принимал никто — половина действий выглядела подписью,
   и попадали на них случайно. Теперь у таких мест два вида, и разница
   осмысленная:

   `действие`  — за кнопкой форма, которая что-то меняет. Выглядит кнопкой.
   `раскрыть`  — за ссылкой текст, который просто читают. Выглядит ссылкой.

   Стрелка вниз у кнопки говорит, что развернётся форма, а не случится
   действие: у «Собрать документ» такой стрелки нет и быть не должно. */

details.действие>summary{
  display:inline-flex;align-items:center;gap:6px;white-space:nowrap;
  list-style:none;cursor:pointer;user-select:none;
  font:inherit;font-size:13px;line-height:1.2;
  border:1px solid var(--line);border-radius:8px;padding:6px 11px;
  background:var(--panel);color:var(--ink);
}
details.действие>summary::-webkit-details-marker{display:none}
details.действие>summary:after{content:"▾";font-size:10px;opacity:.55}
details.действие>summary:hover{border-color:var(--line2)}
details.действие[open]>summary{background:var(--panel2);border-color:var(--line2)}
details.действие[open]>summary:after{content:"▴"}

/* Компактный вид — для строки списка, где таких кнопок десятки подряд и
   полноразмерные утопили бы в себе сами задачи. */
details.действие.мелко>summary{font-size:12px;padding:3px 9px;border-radius:7px}

/* Кнопка с пояснением рядом: раскрывашка, за которой не мелкая правка, а
   целый блок работы. Кнопка настоящая по виду, подпись объясняет, зачем. */
details.разверни>summary{display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  list-style:none;cursor:pointer}
details.разверни>summary::-webkit-details-marker{display:none}
details.разверни>summary small{color:var(--muted);font-size:12px}
details.разверни[open]>summary .btn{background:var(--panel2);border-color:var(--line2);color:var(--ink)}

/* Раскрывашка для чтения: расшифровка до правки, дословная цитата, история
   отправленных сообщений. Действия за ней нет, поэтому и кнопки нет. */
details.раскрыть>summary{
  list-style:none;cursor:pointer;color:var(--accent);font-size:12.5px;
}
details.раскрыть>summary::-webkit-details-marker{display:none}
details.раскрыть>summary:before{content:"▸ ";font-size:10px}
details.раскрыть[open]>summary:before{content:"▾ "}
details.раскрыть>summary:hover{text-decoration:underline}

/* ---------- расписание дня ----------

   Сетка «час × день»: семь колонок, с 08:00 до 22:00. Ячейки крупнее прежних -
   в них лежит название дела, а не только цвет. Границы холста шире рабочих
   часов: вне них человек ставит себе блоки сам, а коллеги забронировать не
   могут - такие ячейки заштрихованы. */
.расписание{display:grid;gap:1px;background:var(--line);border:1px solid var(--line);
            border-radius:10px;overflow:hidden;font-size:12px}
.расписание>div{background:var(--panel);padding:3px;min-height:46px}
.расписание .уголок{background:var(--grid)}
.расписание .шапка-дня{background:var(--grid);text-align:center;padding:7px 4px;
                       font-weight:600;min-height:0;line-height:1.35}
.расписание .шапка-дня form{margin:0}
.расписание .шапка-дня .ссылкой{font-size:10.5px}
.расписание .шапка-дня.сегодня{background:var(--accent-soft);color:var(--accent-ink)}
.расписание .шапка-дня.закрыт{background:var(--late-soft);color:var(--late-ink)}
.расписание .час{background:var(--panel2);color:var(--muted);text-align:right;
                 padding:4px 7px;font-variant-numeric:tabular-nums;min-height:0}
.расписание .ячейка{padding:2px}
.блок{display:flex;align-items:flex-start;width:100%;height:100%;min-height:42px;
      border:0;border-radius:6px;padding:5px 7px;font-size:11.5px;line-height:1.3;
      text-align:left;overflow:hidden;background:var(--grid);color:var(--muted)}
button.блок{cursor:pointer}
.блок.focus{background:var(--wait-soft);color:var(--wait-ink);border-left:3px solid var(--wait)}
.блок.meeting{background:var(--done-soft);color:var(--done-ink);border-left:3px solid var(--done)}
.блок.busy,.блок.off{background:var(--grid);color:var(--muted);border-left:3px solid var(--idle)}
.блок.свободно{background:transparent;color:transparent;border:1px dashed transparent}
.блок.свободно:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-soft);
                     justify-content:center;align-items:center}
.блок.свободно.моё{color:transparent}
.блок.вне,.блок.свободно.вне{background:repeating-linear-gradient(45deg,transparent,transparent 4px,
                             var(--grid) 4px,var(--grid) 8px)}
.legend .sw.focus{background:var(--wait-soft);border-left:3px solid var(--wait)}
.legend .sw.meeting{background:var(--done-soft);border-left:3px solid var(--done)}
.legend .sw.busy{background:var(--grid);border-left:3px solid var(--idle)}
.legend .sw.free{background:var(--panel);border:1px dashed var(--line)}
.legend .sw.вне{background:repeating-linear-gradient(45deg,transparent,transparent 3px,
                var(--grid) 3px,var(--grid) 6px);border:1px solid var(--line)}
.hours{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:6px 16px;margin-bottom:12px}
.hday{display:flex;gap:8px;align-items:center}
.hday label{width:64px;margin:0;color:var(--ink);font-size:12.5px;display:flex;align-items:center;gap:6px}
.hday input[type=time]{width:96px;padding:4px 7px;font-size:12.5px}

/* ---------- вход ---------- */
.login{min-height:100vh;display:flex;align-items:center;justify-content:center;background:var(--bg)}
.login .card{width:340px;padding:24px 26px}
.login h1{font-size:18px;margin-bottom:14px}

/* ---------- совместимость со старой разметкой ----------
   Экраны первого и второго этапов писались под Pico. Классы ниже оставлены,
   чтобы не переписывать их разметку целиком: в новой палитре они выглядят так
   же, как соседние блоки. */
.topbar{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;flex-wrap:wrap}
.grid-2{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:12px 18px}
.stage-tag{display:inline-flex;font-size:11.5px;padding:2px 8px;border-radius:20px;
           background:var(--grid);color:var(--muted);white-space:nowrap}
.late-date{color:var(--late);font-weight:600}
dl.card{display:grid;grid-template-columns:max-content 1fr;gap:4px 14px;border:0;background:transparent;
        margin:0}
dl.card dt{color:var(--muted);font-size:12.5px}
dl.card dd{margin:0;font-size:13px}
details>summary{cursor:pointer}
details[open]>summary{margin-bottom:8px}

/* ---------- узкое окно ---------- */

/* Шапка с кнопкой меню. На широком экране её нет вовсе: сайдбар и так стоит
   слева и никуда не уезжает. */
.мшапка{display:none}

/* Половина экрана ноутбука - это не телефон, но и не полный экран: сайдбар в
   210 пикселей съедает там четверть ширины. Раньше в этом месте он просто
   вставал сверху колонкой на весь экран, и до содержимого приходилось
   прокручивать всё меню целиком - ровно то, чего от адаптива не ждут.
   Теперь он уезжает за левый край и открывается кнопкой поверх страницы. */
@media (max-width:1000px){
  /* На сколько прилипшие шапки разделов должны отступить сверху: под ними
     стоит своя шапка с кнопкой меню. Одно число на всё - иначе прилипший верх
     задач закрывает собой кнопку. */
  /* Строки задаются явно: у каркаса `min-height:100vh`, и без них сетка
     растягивает шапку на треть экрана, лишь бы заполнить высоту. Сайдбар
     своей строки не занимает - он уехал в `position:fixed`. */
  /* `minmax(0,1fr)`, а не `1fr`: у колонки грида ширина по умолчанию не
     меньше содержимого, и одна широкая строка делала всю страницу шире
     экрана - карточка проекта на телефоне уезжала вправо целиком вместе с
     шапкой и меню. То же правило, что у широкого канбана. */
  .app{grid-template-columns:minmax(0,1fr);grid-template-rows:auto 1fr;--мшапка:45px}

  .мшапка{display:flex;align-items:center;gap:10px;position:sticky;top:0;z-index:40;
          background:#151a21;color:#fff;padding:7px 12px;min-height:45px;box-sizing:border-box}
  .мшапка .бургер{background:transparent;border:1px solid #333c47;color:#c9d1d9;
                  padding:4px 10px;font-size:15px;line-height:1.2}
  .мшапка .бургер:hover{border-color:#4a5563;color:#fff}
  .мшапка .назв{font-weight:700;font-size:14px;color:#fff;text-decoration:none}
  .мшапка .назв:hover{text-decoration:none}

  .side{position:fixed;top:0;left:0;bottom:0;width:252px;height:100dvh;z-index:70;
        overflow-y:auto;transform:translateX(-100%);transition:transform .18s ease;
        box-shadow:2px 0 18px rgba(6,10,16,.45)}
  .app.меню-открыто .side{transform:none}
  .подложка{position:fixed;inset:0;background:rgba(6,10,16,.5);z-index:60}

  .main{padding:14px 14px 50px}
  /* Прилипшие блоки разделов встают под шапку, а не под неё же. */
  .зверх{top:var(--мшапка)}
  .grid2,.wrk{grid-template-columns:1fr}
  .row{grid-template-columns:1fr}
  /* Широкая таблица прокручивается внутри своей карточки: страница, едущая
     вбок целиком, уводит за край и меню, и шапку. */
  .tblcard{overflow-x:auto}
  .tblcard table{min-width:620px}
}

@media (prefers-reduced-motion:reduce){.side,.згруппа .стрелка{transition:none}}

/* Текст, пришедший markdown'ом: саммари встречи, причёсанная расшифровка.
   Реплики идут абзацами, заголовки саммари - заголовками, а не решётками. */
.proza p{margin:0 0 9px}
.proza h3,.proza h4,.proza h5{margin:14px 0 6px;font-size:13.5px}
.proza ul{margin:0 0 9px;padding-left:20px}
.proza li{margin:2px 0}
.proza strong{font-weight:600}

/* Разница редакций ТЗ. Цвета те же, что у статусов: зелёное - добавленное,
   красное - убранное. Строки не переносятся посередине слова, но длинную
   строку markdown надо видеть целиком, поэтому перенос по словам. */
.diff{border:1px solid var(--line);border-radius:10px;overflow:hidden;
      font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.82rem}
.diff>div{padding:3px 10px;white-space:pre-wrap;word-break:break-word}
.diff-add{background:var(--done-soft);color:var(--done-ink)}
.diff-del{background:var(--late-soft);color:var(--late-ink)}
.diff-ctx{color:var(--muted)}
.diff-skip{background:var(--bg);color:var(--idle);text-align:center;padding:2px}

/* Чужая задача: кружок «сделано» неактивен - её видно, но не тронуть. */
.circ.чужая{opacity:.45;cursor:not-allowed}

/* Участники планёрки: список галочек в строку, а не столбиком в километр. */
.участники{display:flex;flex-wrap:wrap;gap:.5rem 1rem;margin:.3rem 0}
.чекбокс{display:flex;align-items:center;gap:.4rem;width:auto;margin:0}
.чекбокс input{width:auto;margin:0}

/* ── планёрки ───────────────────────────────────────────────────────────── */

/* Строка встречи в списке: название и метки под ним. Вся строка - ссылка:
   на планёрку заходят, чтобы дописать решение, а не чтобы разглядывать её. */
.встреча-строка{display:block;padding:9px 0;border-bottom:1px solid var(--line);color:inherit;
   text-decoration:none}
.встреча-строка .dn{font-size:13.5px;font-weight:500}
.встреча-строка:last-child{border:0}
.встреча-строка:hover .dn{color:var(--accent)}
.метки{display:flex;gap:5px;flex-wrap:wrap;margin-top:4px}

/* Пункт повестки. Вопрос сверху, решение под ним - в поле, которое видно
   всегда: раскрывающийся блок на встрече не открывают. */
.пункт{padding:12px 0;border-bottom:1px solid var(--line)}
.пункт:last-child{border:0}
.пункт.разобран{background:linear-gradient(90deg,var(--done-soft),transparent 40%)}
.пункт .вопрос{display:flex;gap:8px;align-items:baseline;justify-content:space-between}
.пункт .вопрос b{font-size:13.5px;font-weight:600}
.пункт form{display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin:6px 0 0}
.пункт input[type=text],.пункт textarea{width:auto;flex:1;min-width:18rem;
   padding:5px 9px;font-size:12.5px}
.пункт select,.пункт button{width:auto;padding:5px 10px;font-size:12.5px}
/* Кнопка, которая выглядит ссылкой: «убрать пункт» рядом с решением не
   должна спорить за внимание с «Сохранить». */
.ссылкой{width:auto;background:none;border:0;padding:0;color:var(--muted);
   font-size:11.5px;text-decoration:underline;cursor:pointer}
.ссылкой:hover{color:var(--late)}
.протокол{white-space:pre-wrap;font-size:12.5px;line-height:1.5;background:var(--panel2);
   border:1px solid var(--line);border-radius:8px;padding:12px;max-height:22rem;overflow:auto}

/* ---------- база знаний ---------- */

/* Свой поиск, а не общий из сайдбара: тот ведёт в карточку клиента и в
   документ, а здесь ищут слово внутри инструкции. */
.кбпоиск{display:flex;gap:8px;align-items:center;margin-bottom:12px;flex-wrap:wrap}
.кбпоиск input[type=search]{flex:1;min-width:14rem;max-width:32rem}
.кбпоиск button{width:auto}

.кбметки{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:12px}

.кбсписок{display:flex;flex-direction:column;gap:8px}
/* Вся строка - ссылка: в статью заходят читать, а не разглядывать список. */
.кбстрока{display:block;background:var(--panel);border:1px solid var(--line);
          border-radius:11px;padding:12px 15px;color:inherit;text-decoration:none}
.кбстрока:hover{border-color:var(--accent);text-decoration:none}
.кбстрока .имя{font-weight:600;font-size:14px}
.кбстрока:hover .имя{color:var(--accent)}
.кбстрока .закреп{color:var(--accent);font-size:10px;margin-right:3px}
/* Первые строки статьи вместо аннотации: аннотацию не заполняют, а начало
   текста отвечает на вопрос «та ли это статья» не хуже. */
.кбстрока .выжимка{color:var(--muted);font-size:12.5px;line-height:1.5;margin-top:3px}
.кбстрока .метки{display:flex;flex-wrap:wrap;gap:5px;align-items:center;margin-top:7px}

/* Текст статьи читают целиком, а не проглядывают: строка шире 70 знаков
   теряется глазом на переносе. */
.кбтекст{max-width:44rem;font-size:14px;line-height:1.6}
.кбтекст h3,.кбтекст h4,.кбтекст h5{margin:18px 0 7px}
.кбтекст ul{margin:0 0 11px;padding-left:22px}

.кбредакция{margin-bottom:8px}
.кбредакция summary{font-size:12.5px;color:var(--muted)}
.кбредакция summary b{color:var(--ink)}
.кбредакция .кбтекст{margin-top:10px;padding-top:10px;border-top:1px solid var(--line)}

/* Платежи после первого. Свёрнуты: у договора с предоплатой 100% платёж один,
   и два пустых поля рядом с суммой договора только просят их заполнить -
   раньше в них и ставили нули, а потом вычёркивали абзацы из документа. */
.доплатежи{margin-bottom:14px}
.доплатежи>summary{cursor:pointer;font-size:13px;color:var(--accent);
                   display:inline-flex;align-items:center;gap:6px}
.доплатежи>summary:hover{text-decoration:underline}

/* ---------- проекты (разработка) ---------- */

/* Канбан с парковкой. Колонка делится по вертикали: сверху то, где ход за
   нами, внизу - то, что стоит и ждёт клиента. Раньше это было видно только
   бейджем на карточке, и «пять проектов в колонке» означало что угодно. */
.лаб-отбор{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:12px}
.лаб-отбор select{width:auto;max-width:18rem}
.лаб-отбор .муть{font-size:12.5px;color:var(--muted)}

.лподсказка{margin:0 0 10px}
/* Раздел, который кончается не текстом, а нижней кромкой экрана:
   нижний отступ страницы ему только мешает. Класс ставит `lab.js`. */
.main.во-весь-экран{padding-bottom:12px}

/* Доска: две полосы в одной прокрутке. Сверху работа, снизу - парковка, и
   колонка парковки стоит ровно под своим этапом. Две отдельные прокрутки
   разъехались бы на первом же движении мыши, поэтому полосы делят одну сетку
   и одну колоночную раскладку.

   Доска занимает экран целиком, работа прокручивается внутри себя, парковка
   держит нижнюю кромку: раньше она была хвостом длинной страницы, и чтобы
   отправить проект стоять, надо было сначала до неё доскроллить. Точную
   высоту ставит `lab.js` по месту - над доской шапка, отбор и подсказка, и на
   узком окне они занимают вдвое больше. */
.лкан{display:grid;grid-template-rows:1fr auto;overflow-x:auto;
      height:calc(100dvh - 210px);min-height:300px}
.лверх,.лниз{display:grid;gap:8px;align-items:start;
             grid-template-columns:22px repeat(var(--колонок,4),minmax(200px,1fr))}
.лверх{overflow-y:auto;min-height:0;padding-bottom:8px}
/* Пунктир во всю ширину - граница полосы, а не украшение: он отвечает на
   вопрос «где кончается работа». */
.лниз{border-top:2px dashed var(--line2);padding-top:9px;align-items:stretch}

/* Поле под вертикальную подпись. Прилипает к левому краю: при прокрутке вбок
   подпись обязана оставаться на месте, иначе непонятно, что это за полоса. */
.лполе{position:sticky;left:0;z-index:2;background:var(--bg);
       display:flex;align-items:center;justify-content:center}
.лвбок{writing-mode:vertical-rl;transform:rotate(180deg);display:block;
       font-size:11px;letter-spacing:.06em;color:var(--muted);text-align:right;
       padding:2px 0}

.лкол{background:var(--grid);border-radius:11px;padding:9px;min-height:120px}
.лкол.горит{background:var(--late-soft)}
.лшапка{display:flex;align-items:center;gap:6px;margin-bottom:8px}
.лшапка .номер{width:19px;height:19px;flex:0 0 19px;border-radius:5px;background:var(--line2);
                color:var(--muted);font-size:10.5px;display:flex;align-items:center;
                justify-content:center;font-weight:700}
.лкол.горит .лшапка .номер{background:var(--late);color:#fff}
.лшапка h3{margin:0;font-size:11.5px;line-height:1.25;font-weight:600;flex:1}
.лшапка .счёт{background:var(--panel);border-radius:9px;padding:0 6px;font-size:10.5px;
              font-weight:600;color:var(--muted)}
.лпусто{font-size:10.5px;color:var(--muted);padding:4px 2px}

/* Стоянка одного этапа. Пустая тоже рисуется: зона на одном и том же месте
   читается как зона, а появляющаяся и исчезающая - как сбой вёрстки. */
.лстоянка{background:var(--grid);border-radius:11px;padding:9px;min-height:64px;
          max-height:34vh;overflow-y:auto}
.лстоянка.занята{background:var(--wait-soft)}

.лкарта{display:block;background:var(--panel);border:1px solid var(--line);border-left:3px solid var(--line2);
        border-radius:8px;padding:8px 9px;margin-bottom:6px;color:inherit;text-decoration:none}
.лкарта:hover{box-shadow:0 2px 6px var(--тень);text-decoration:none}
.лкарта.now{border-left-color:var(--now)}
.лкарта.late{border-left-color:var(--late)}
.лкарта.wait{border-left-color:var(--wait)}
.лкарта .имя{font-weight:600;font-size:12px;line-height:1.25}
.лкарта .клиент{color:var(--muted);font-size:10.5px;margin-bottom:6px}
.лкарта .низ{display:flex;justify-content:space-between;gap:6px;font-size:10.5px;color:var(--muted)}
.лкарта .низ .этап{min-width:0;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;
                   -webkit-box-orient:vertical}
.лкарта .низ .срок{flex:0 0 auto;font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums}
.лкарта .низ .срок.горит{color:var(--late)}
.лкарта .стоит{font-size:10px;color:var(--muted);margin-top:4px}
/* Перетаскивание. Подсвечиваются только зоны своей колонки: колонка - это
   этап, а этап перетаскиванием не закрывают. */
.лкарта[draggable]{cursor:grab}
.лкарта.едет{opacity:.45;cursor:grabbing}
/* `pointer-events:none` на карточке во время переноса ставить нельзя: Chromium
   теряет источник переноса и вешает его насмерть - карточка не доезжает
   никуда, и «перетаскивание не работает» выглядит именно так. Проверено
   17.09.2026 настоящим переносом в браузере. Класть на зону, а не на карточку
   под курсором, и без этого умеет `lab.js`: он ищет зону через `closest`. */
body.тащим [data-зона]{transition:background .12s,border-color .12s}
/* Пока тащат, колонки этапов вытягиваются на всю высоту полосы: у колонки с
   одной карточкой пустое место под ней - тоже зона, и промахиваться мимо неё
   человек не должен. Без переноса колонка живёт по содержимому - так на
   прототипе, и так доска читается как таблица, а не как четыре пустых листа. */
body.тащим .лверх{align-items:stretch}
.лкол.цель{outline:2px dashed var(--line2);outline-offset:-3px}
.лстоянка.цель{outline:2px dashed var(--wait);outline-offset:-3px;
               background:var(--wait-soft)}
.лкол.над{outline-color:var(--now);background:var(--panel)}
.лстоянка.над{background:var(--wait);outline-style:solid}

/* Полоса этапов на карточке проекта. Короткий список вместо подробного
   таймлайна: на карточке нужен ответ «где мы сейчас», а не четыре колонки дат
   по каждому этапу. Прокручивается вбок - этапов бывает одиннадцать. */
.лполоса{display:flex;gap:10px;overflow-x:auto;padding-bottom:2px;margin-bottom:6px;
         scrollbar-width:none}
.лполоса::-webkit-scrollbar{display:none}
.лрамка{position:relative}
/* Затенение у края - только когда вправо действительно есть что листать.
   Класс ставит `lab.js`: постоянная тень врала бы на коротких воронках. */
.лрамка::after{content:"";position:absolute;inset:0 0 6px auto;width:64px;
               pointer-events:none;opacity:0;transition:opacity .15s;
               background:linear-gradient(to right,transparent,var(--bg))}
.лрамка.есть-хвост::after{opacity:1}
.лрамка.есть-голова::before{content:"";position:absolute;inset:0 auto 6px 0;width:64px;
               pointer-events:none;z-index:1;
               background:linear-gradient(to left,transparent,var(--bg))}
.лшаг{flex:1 0 132px;min-width:132px}
.лшаг .черта{height:3px;border-radius:2px;background:var(--line);margin-bottom:7px}
.лшаг .имя{font-size:11.5px;line-height:1.3;color:var(--muted);display:flex;
           align-items:baseline;gap:5px}
.лшаг .номер{font-variant-numeric:tabular-nums;color:var(--line2);font-weight:600}
.лшаг .значок{background:var(--panel2);border-radius:8px;padding:0 5px;font-size:10px;
              font-weight:600;color:var(--muted)}
.лшаг.пройден .черта{background:var(--done)}
.лшаг.пройден .имя{color:var(--muted)}
.лшаг.идёт .черта{background:var(--accent)}
.лшаг.идёт .имя{color:var(--ink);font-weight:600}
.лшаг.идёт .номер{color:var(--accent)}
.лгде{font-size:12.5px;color:var(--muted);margin-bottom:14px}
.лгде .муть{color:var(--line2)}

/* Задачи этапа: галочка, название, исполнитель и срок. Ничего больше - всё
   остальное у задачи есть в разделе задач, и дублировать его здесь значит
   заводить второй список дел. */
.лдела{display:flex;flex-direction:column;gap:6px}
.лдело{display:flex;align-items:flex-start;gap:9px;background:var(--panel2);
       border-radius:9px;padding:8px 10px}
.лдело .что a{color:inherit;text-decoration:none;font-size:13px;font-weight:500}
.лдело .что a:hover{text-decoration:underline}
.лдело .мелко{font-size:11px;color:var(--muted);margin-top:2px}
.лдело.сделано .что a{color:var(--muted);text-decoration:line-through}
.галка{width:19px;height:19px;flex:0 0 19px;border:1.5px solid var(--line2);
       border-radius:5px;background:var(--panel);padding:0;font-size:12px;
       line-height:1;color:var(--done);cursor:pointer;margin-top:1px}
.галка:hover{border-color:var(--accent)}
.лдело.сделано .галка{border-color:var(--done);background:var(--done-soft)}
.лпусто-дела{font-size:12px;color:var(--muted);padding:2px}
/* Строка добавления. Раньше это было поле-ящик во всю ширину экрана, и
   именно от них карточка выглядела тяжёлой: три пустых прямоугольника по
   тысяче пикселей на экран. Теперь строка тихая - плюс и место для текста, -
   а рамка появляется, когда в поле метят или пишут. */
.лновое{display:flex;gap:8px;align-items:center;margin-top:4px;padding:5px 0;
        flex-wrap:wrap}
.лновое input{margin:0}
.лновое::before{content:"+";width:17px;height:17px;flex:0 0 17px;border-radius:5px;
                border:1.5px dashed var(--line2);color:var(--muted);font-size:13px;
                line-height:1;display:flex;align-items:center;justify-content:center}
/* Название - во всю оставшуюся ширину, но не больше: растягиваться на
   полтора экрана полю не надо. По имени, а не по типу: `dates.js` подменяет
   поле даты на текстовое с русским форматом, и правило «все input[type=text]
   тянутся» раздувало бы именно его. */
.лновое input[name=title],.лновое input[name=text]{flex:1;min-width:0;max-width:34rem;
                                                   border-color:transparent;
                                                   background:transparent;padding-left:0}
.лновое:hover input[name=title],.лновое:hover input[name=text],
.лновое input[name=title]:focus,.лновое input[name=text]:focus{
  border-color:var(--line2);background:var(--panel);padding-left:10px}
/* Ссылка: название и адрес тянутся поровну, дата и кнопка - по содержимому. */
.лновое input[type=url]{flex:1;min-width:0;max-width:24rem}
.лновое select{width:auto;max-width:11rem;flex:0 0 auto}
.лновое .дата-поле{width:8.4rem;flex:0 0 auto}
/* «Кто решил» - узкое именованное поле. Без ширины оно сжималось в огрызок
   рядом с растянутым текстом решения. */
.лновое .лкто{width:10rem;flex:0 0 auto}
/* Подпись-счётчик рядом с заголовком блока: «0 из 3», название этапа. */
.лсчёт-пунктов{font-weight:400;color:var(--muted);text-transform:none;
               letter-spacing:0;font-size:11px;margin-left:6px}


/* База знаний: дерево разделов слева, список статей справа. Дерево - два
   уровня и ровно два: раздел и статья. Собрано на `<details>`, поэтому
   сворачивание умеет сам браузер; свёрнутость помнит `kb.js`. */
.кбэкран{display:grid;grid-template-columns:230px minmax(0,1fr);gap:16px;align-items:start}
.кбэкран.без-дерева{grid-template-columns:minmax(0,1fr)}
.кбэкран.без-дерева .кбдерево{display:none}
.кбдерево{background:var(--panel);border:1px solid var(--line);border-radius:11px;
          padding:8px;position:sticky;top:14px;max-height:calc(100dvh - 28px);
          overflow-y:auto;font-size:12.5px}
.кбдерево .кбвсе{display:flex;justify-content:space-between;align-items:center;gap:6px;
                 padding:6px 8px;border-radius:7px;color:var(--ink);text-decoration:none;
                 font-weight:600}
.кбдерево .кбвсе:hover,.кбдерево .кблист:hover,.кбдерево summary:hover{background:var(--panel2)}
.кбдерево .кбвсе.on{background:var(--accent-soft);color:var(--accent-ink)}
.кбузел summary{display:flex;align-items:center;gap:6px;padding:5px 8px;border-radius:7px;
                cursor:pointer;list-style:none;color:var(--ink)}
.кбузел summary::-webkit-details-marker{display:none}
.кбузел summary::before{content:"▸";color:var(--muted);font-size:10px;width:9px;flex:0 0 9px}
.кбузел[open] summary::before{content:"▾"}
.кбузел summary .имя{flex:1;min-width:0;line-height:1.25}
.кбдерево .cnt{background:var(--panel2);border-radius:9px;padding:0 5px;font-size:10.5px;
               color:var(--muted);font-weight:600}
.кбдерево .кблист,.кбдерево .кбвесь{display:block;padding:4px 8px 4px 23px;border-radius:7px;
                                    color:var(--muted);text-decoration:none;line-height:1.3}
.кбдерево .кблист{color:var(--ink)}
.кбдерево .кбвесь{font-size:11.5px}
.кбдерево .кбвесь.on{color:var(--accent-ink);font-weight:600}
.кбдерево .чрн{font-size:9.5px;color:var(--wait-ink);background:var(--wait-soft);
               border-radius:6px;padding:0 4px;margin-left:3px;white-space:nowrap}
.кбпусто{padding:4px 8px 4px 23px;color:var(--muted);font-size:11.5px}
/* Кнопка-переключатель дерева стоит в ряду вкладок и выглядит как вкладка. */
.кбглавное .tabs{flex-wrap:wrap}
/* Узкое окно: дерево встаёт над списком, а не жмёт его в ленту слов. */
@media (max-width:1000px){
  .кбэкран{grid-template-columns:minmax(0,1fr)}
  .кбдерево{position:static;max-height:none}
}
.tabs .кбкнопка{background:transparent;border:0;font:inherit;font-size:12.5px;
                color:var(--muted);cursor:pointer;padding:6px 10px;border-radius:8px}
.tabs .кбкнопка:hover{background:var(--panel2);color:var(--ink)}

/* Картинки и таблицы в статье базы знаний. Инструкция «куда нажать» без
   скриншота не работает, а таблица этапов без границ читается как каша. */
.кб-картинка{margin:10px 0;max-width:100%}
.кб-картинка img{max-width:100%;border:1px solid var(--line);border-radius:8px;display:block}
.кб-картинка figcaption{font-size:11.5px;color:var(--muted);margin-top:4px}
.кб-таблица{border-collapse:collapse;margin:10px 0;font-size:12.5px;width:auto}
.кб-таблица th,.кб-таблица td{border:1px solid var(--line);padding:5px 9px;text-align:left;
                              vertical-align:top}
.кб-таблица th{background:var(--panel2);font-weight:600}
/* Блок кода - это шаблон сообщения клиенту: его копируют целиком, поэтому он
   и выглядит как отдельный кусок текста, а не как абзац. */
.кодовый{background:var(--panel2);border:1px solid var(--line);border-radius:8px;
         padding:9px 11px;margin:10px 0;font:inherit;font-size:12.5px;
         white-space:pre-wrap;overflow-x:auto}
.кбкартинки{margin-top:12px}
.кбкартинки summary{display:inline-flex;cursor:pointer}
.кбкартинки form{display:flex;gap:8px;align-items:center;flex-wrap:wrap}

.лвехи{display:flex;flex-wrap:wrap;gap:6px 14px;margin-bottom:6px}
.лвехи .веха{font-size:11.5px;color:var(--muted)}
.лвехи .веха.есть{color:var(--done-ink);font-weight:500}

/* Раздел ТЗ: список по клиентам. Строка, а не таблица: у ТЗ длинные
   названия, и на телефоне таблица из четырёх колонок превращается в ленту
   прокрутки вбок. */
.тзпоиск{display:flex;gap:8px;align-items:center;margin-bottom:14px}
.тзпоиск input{width:min(420px,100%)}
.тзсписок{display:flex;flex-direction:column;gap:6px}
.тзстрока{display:grid;grid-template-columns:minmax(0,1fr) 104px 128px 150px;gap:12px;
          align-items:baseline;background:var(--panel2);border-radius:9px;
          padding:10px 12px;color:var(--ink);text-decoration:none;font-size:13.5px}
.тзстрока:hover{background:var(--panel)}
.тзстрока .имя{font-weight:500}
.тзстрока .имя .мелко{display:block;font-size:11.5px;color:var(--muted);
                      font-weight:400;margin-top:2px}
.тзстрока .дата{font-variant-numeric:tabular-nums;font-size:12.5px;color:var(--muted)}
.тзстрока .сост,.тзстрока .где{font-size:12px;color:var(--muted)}
@media (max-width:1000px){
  .тзстрока{grid-template-columns:minmax(0,1fr) auto;row-gap:3px}
  .тзстрока .сост,.тзстрока .где{grid-column:1}
  .тзстрока .дата{grid-column:2;grid-row:1}
}

/* Название карточки на доске: «клиент — робот». Клиент выделен: по нему
   карточку и находят глазами, а название работы у соседних проектов часто
   одинаковое («робот для входящих» у троих сразу). */
.лкарта .имя .клиент{font-weight:600}
.лкарта .имя .тире{color:var(--muted);margin:0 4px 0 0}

/* Шапка карточки: код проекта, этап, здоровье и два счётчика. Два счётчика
   вместо общего сдвига - сразу видно, чья задержка: ожидание клиента срок не
   съедает, а прибавляет. */
.лкод{font-family:var(--моно,ui-monospace,Menlo,Consolas,monospace);
      letter-spacing:.02em;margin-right:8px;color:var(--ink)}
.лшапка{display:flex;flex-wrap:wrap;align-items:center;gap:8px 18px;margin-top:8px}
/* Действия карточки держатся правого края, даже когда шапка перенесла их на
   свою строку: слева они читаются как часть заголовка. */
.head:has(.лшапка) .acts{margin-left:auto}
/* Левая половина шапки обязана уметь сжиматься. У элемента сетки `min-width`
   по умолчанию равен содержимому: без этого строка с этапом, здоровьем и
   счётчиками не переносилась вовсе - она просто делала страницу шире экрана,
   и на телефоне карточка уезжала вправо целиком. */
.head:has(.лшапка)>div:first-child{min-width:0;flex:1 1 20rem}
.лздоровье select{font-size:12px;padding:3px 8px;width:auto;border-radius:20px}
.лздоровье select.on_track{background:var(--done-soft);color:var(--done-ink);
                           border-color:var(--done-soft)}
.лздоровье select.at_risk{background:var(--wait-soft);color:var(--wait-ink);
                          border-color:var(--wait-soft)}
.лздоровье select.behind{background:var(--late-soft);color:var(--late-ink);
                         border-color:var(--late-soft)}
.лсчёт{display:flex;flex-direction:column;line-height:1.2}
.лсчёт .подпись{font-size:10px;text-transform:uppercase;letter-spacing:.06em;
                color:var(--muted)}
.лсчёт b{font-size:15px;font-variant-numeric:tabular-nums}
.лсчёт b.горит{color:var(--late)}
/* Прогноз под сроком этапа: он стоит рядом с планом, а не вместо него -
   план это обещание, по которому считается «уложились или нет». */
.лсчёт .мелко{font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums}

/* Полоса этапов кликается: нажатие только рассказывает об этапе. */
/* Кнопка, а не div: по этапу нажимают. Но содержимое кнопки браузер
   центрирует по вертикали, и у коротких названий черта уезжала вниз на
   пятнадцать пикселей - полоса выглядела разнобоем. Кнопка-колонка кладёт
   содержимое от верха, как обычный блок. */
.лполоса button.лшаг{all:unset;cursor:pointer;flex:1 0 118px;min-width:118px;
                     display:flex;flex-direction:column;justify-content:flex-start}
/* Имя - ровно две строки у всех: у одного этапа название в слово, у другого
   в пять, и без общей высоты низ полосы рвался. Полное имя - в подсказке. */
.лполоса button.лшаг .имя .текст{display:-webkit-box;-webkit-line-clamp:2;
                                 -webkit-box-orient:vertical;overflow:hidden;
                                 min-height:2.6em}
.лполоса button.лшаг.идёт{flex:2 0 200px;min-width:200px}
.лполоса button.лшаг .черта{display:block;height:3px;border-radius:2px;
                            background:var(--line);margin-bottom:7px}
.лполоса button.лшаг .имя{display:flex;align-items:baseline;gap:5px;font-size:11.5px;
                          line-height:1.3;color:var(--muted)}
/* Состояния этапа повторяются здесь же: у кнопки специфичность выше, и без
   этого пройденные этапы теряли цвет. */
.лполоса button.лшаг.пройден .черта{background:var(--done)}
.лполоса button.лшаг.идёт .черта{background:var(--accent)}
.лполоса button.лшаг.идёт .имя{color:var(--ink);font-weight:600}
.лполоса button.лшаг.идёт .номер{color:var(--accent)}
.лполоса button.лшаг:hover .имя{color:var(--ink)}
.лполоса button.лшаг:focus-visible{outline:2px solid var(--accent);outline-offset:3px}

/* Ход и таймер шага. Полоса под шапкой отвечает на два вопроса сразу: у кого
   сейчас ход и сколько шаг уже идёт. Цвет ожидания, а не тревоги, когда ход у
   клиента: это не просрочка, наш счётчик просто стоит. */
.лход{display:flex;flex-wrap:wrap;gap:12px 24px;align-items:center;
      justify-content:space-between;padding:12px 16px;border-radius:11px;
      margin-bottom:12px;font-size:13.5px}
.лход.мы{background:var(--accent-soft);color:var(--accent-ink)}
.лход.клиент{background:var(--wait-soft);color:var(--wait-ink)}
.лход .чей{display:flex;align-items:center;gap:9px;font-weight:500;flex:1 1 280px;
           flex-wrap:wrap}
.лход .чей .с{color:var(--muted);font-weight:400;margin-left:4px}
.лход .точка{width:9px;height:9px;border-radius:50%;background:currentColor;flex:none}
.лход .часы{flex:0 1 340px;min-width:240px;display:flex;flex-direction:column;gap:5px}
.лход .верх{display:flex;align-items:baseline;gap:9px;flex-wrap:wrap}
.лход .подпись,.лход .из{font-size:11.5px;color:var(--muted)}
.лход .верх b{font-size:19px;font-weight:600;font-variant-numeric:tabular-nums;
              letter-spacing:-.01em;color:var(--ink)}
.лход .полоска{height:7px;border-radius:99px;background:var(--panel);overflow:hidden;
               border:1px solid var(--line)}
.лход .полоска i{display:block;height:100%;width:0;background:currentColor;
                 border-radius:99px;transition:width .4s}
.лход .низ{font-size:11.5px;color:var(--muted);font-variant-numeric:tabular-nums}
/* Вышли за норматив - полоса краснеет, и «осталось» меняется на «сверх». */
.лход.перебор{background:var(--late-soft);color:var(--late-ink)}
.лход.перебор .низ{color:var(--late);font-weight:600}

/* Главное действие карточки: одна кнопка на все шаги, рядом «Ещё» с
   возвратом. Подсказка под кнопкой говорит, чего не хватает или к кому
   перейдёт ход. */
.лпереход{display:flex;flex-direction:column;gap:5px;align-items:flex-end}
.лкнопки{display:flex;gap:8px;align-items:center}
.лпереход .муть{font-size:11.5px;color:var(--muted);text-align:right;max-width:22rem}
@media (max-width:1000px){
  .лпереход{align-items:flex-start}
  .лпереход .муть{text-align:left}
}

/* Шаги текущего этапа: на тестировании их шесть, и по доске не понять, на
   каком цикле проект стоит. */
.лциклы{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px;font-size:11.5px}
.лциклы span{padding:2px 8px;border-radius:7px;border:1px solid var(--line);
             color:var(--muted)}
.лциклы span.пройден{color:var(--done-ink);border-color:var(--done-soft);
                     background:var(--done-soft)}
.лциклы span.идёт{color:var(--ink);border-color:var(--ink);font-weight:600}

/* Вкладки карточки. Ссылками, а не скриптом: открытая вкладка попадает в
   адрес, и действие возвращает человека туда, откуда он его начал. */
.лвкладки{margin:14px 0 16px}

/* Два списка рядом: «ждём от клиента» и «открытые вопросы», ссылки и решения
   в паспорте. На узком окне встают друг под друга. */
.лдва{display:grid;grid-template-columns:1fr 1fr;gap:14px;align-items:start;
      margin-top:18px}
.лдва h2{margin:0 0 9px}
@media (max-width:1000px){.лдва{grid-template-columns:minmax(0,1fr)}}

.лпункт .срок{margin-left:auto;font-size:11.5px;color:var(--muted);white-space:nowrap;
              font-variant-numeric:tabular-nums}
.лпункт .что{flex:1;min-width:0}
.лпункт .что .мелко{display:block;font-size:11px;color:var(--muted);margin-top:2px}
.убрать{background:none;border:0;color:var(--muted);font-size:15px;line-height:1;
        padding:0 2px;cursor:pointer;width:auto}
.убрать:hover{color:var(--late)}

/* Комментарии к этапу: лента с автором и датой. */
.лкомменты{display:flex;flex-direction:column;gap:8px}
.лкоммент{background:var(--panel2);border-radius:9px;padding:9px 12px;font-size:13.5px}
.лкоммент .мелко{font-size:11.5px;color:var(--muted);margin-bottom:3px}
.лновый-коммент{display:flex;flex-direction:column;gap:6px;align-items:flex-start}
.лновый-коммент textarea{width:100%}

/* Паспорт: сводка, команда по ролям, клиент, ссылки. */
.лпаспорт{background:var(--panel);border:1px solid var(--line);border-radius:12px;
          padding:16px 18px;margin-bottom:18px}
.лпаспорт h2{margin:14px 0 9px}
.лсводка{display:block}
/* Одна строка - значит одна строка: поле во всю ширину экрана обещает абзац. */
.лсводка input{width:100%;max-width:46rem}
.лкоманда{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:10px}
.лпары{display:grid;grid-template-columns:auto 1fr;gap:5px 14px;font-size:13.5px;
       align-items:baseline}
.лпары span{color:var(--muted);font-size:12px}
.лссылки{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px}
.лссылка{display:inline-flex;align-items:center;gap:4px;border:1px solid var(--line);
         background:var(--panel);border-radius:7px;padding:3px 6px 3px 10px;font-size:12.5px}
.лссылка a{color:var(--accent-ink);text-decoration:none}
.лссылка a:hover{text-decoration:underline}

/* История: то же, что в свёрнутом блоке, только целиком. */
.лжурнал{display:flex;flex-direction:column;gap:4px}

/* Задачи проекта: строка, а не таблица - на телефоне таблица из пяти колонок
   превращается в ленту прокрутки. Статус - кнопка: нажал, сменился. */
.лзаголовок{display:flex;align-items:baseline;justify-content:space-between;gap:12px;
            flex-wrap:wrap;margin-bottom:9px}
.лзадачи{display:flex;flex-direction:column;gap:6px}
.лзадача{display:grid;grid-template-columns:minmax(0,1fr) 150px 104px 128px 96px;
         gap:10px;align-items:center;background:var(--panel2);border-radius:9px;
         padding:9px 12px;font-size:13px}
.лзадача .что{color:inherit;text-decoration:none;font-weight:500}
.лзадача .что:hover{text-decoration:underline}
.лзадача .кто,.лзадача .срок,.лзадача .этап{font-size:12px;color:var(--muted)}
.лзадача .срок{font-variant-numeric:tabular-nums}
.лзадача.сделано .что{color:var(--muted);text-decoration:line-through}
.статус{font:inherit;font-size:11.5px;font-weight:500;border:1px solid var(--line);
        background:var(--panel);border-radius:20px;padding:2px 10px;cursor:pointer;
        width:auto;white-space:nowrap}
.статус:hover{border-color:var(--accent)}
.статус.in_progress{background:var(--accent-soft);color:var(--accent-ink);
                    border-color:var(--accent-soft)}
.статус.done{background:var(--done-soft);color:var(--done-ink);border-color:var(--done-soft)}
/* Заготовки из шаблона этапа: ещё не задачи, поэтому пунктир, а не плашка. */
.лзаготовки{display:flex;flex-direction:column;gap:6px;margin-top:10px}
.лзаготовки .лзадача{grid-template-columns:minmax(0,1fr) 150px 170px 96px;
                     background:none;border:1px dashed var(--line)}
@media (max-width:1000px){
  .лзадача,.лзаготовки .лзадача{grid-template-columns:minmax(0,1fr) auto;row-gap:3px}
  .лзадача .кто,.лзадача .срок,.лзадача .этап{grid-column:1}
  .лзадача form{grid-column:2;grid-row:1}
}

/* Чеклист шага: галочка та же, что у задач - и там, и там это «сделано». */
/* Пункт - строка с разделителем, а не серая плашка. Плашки были нужны, пока
   списки лежали прямо на странице; внутри панели они складывались в лесенку
   из закруглённых прямоугольников, и взгляду не за что было зацепиться. */
.лчеклист{display:flex;flex-direction:column}
.лпункт{display:flex;align-items:center;gap:10px;padding:7px 2px;margin:0;
        border-bottom:1px solid var(--line);font-size:13.5px}
.лчеклист>.лпункт:last-of-type{border-bottom:0}
.лпункт .что{line-height:1.35}
.лпункт.отмечен .что{color:var(--muted);text-decoration:line-through}
.лпункт.отмечен .галка{border-color:var(--done);background:var(--done-soft)}

/* Переходы по этапам: кто и когда двигал. Свёрнуто - на `<details>`, чтобы
   сворачивал сам браузер. В закрытом виде это одна строка: последняя правка
   и её автор, дальше открывают, если сроки уехали и надо понять с какого дня. */
.лпереходы{background:var(--panel);border:1px solid var(--line);border-radius:11px;
           padding:8px 12px;margin-bottom:12px;font-size:12.5px}
.лпереходы summary{cursor:pointer;list-style:none;display:flex;align-items:baseline;
                   gap:8px;color:var(--ink)}
.лпереходы summary::-webkit-details-marker{display:none}
.лпереходы summary::before{content:"▸";color:var(--muted);font-size:10px}
.лпереходы[open] summary::before{content:"▾"}
.лпереходы summary .мелко{font-size:11.5px;color:var(--muted)}
.лзапись{display:grid;grid-template-columns:118px minmax(0,1fr) auto;gap:10px;
         padding:5px 0 0 17px;color:var(--muted);line-height:1.35;font-size:12.5px}
.лжурнал .лзапись{padding:8px 12px;background:var(--panel2);border-radius:9px}
.лзапись .когда{font-variant-numeric:tabular-nums;font-size:11.5px}
.лзапись .что{color:var(--ink)}
.лзапись .кто{font-size:11.5px;white-space:nowrap}

/* Документы проекта: договор, счета и акты со статусами. Без них плитка
   «Деньги» - число, которое нечем проверить. У счёта на месте статуса стоит
   оплата: вопрос к счёту всегда один. */
.лдоки{display:flex;flex-direction:column;gap:6px}
.лдок{display:grid;grid-template-columns:74px minmax(0,1fr) 104px 150px;gap:10px;
      align-items:baseline;background:var(--panel2);border-radius:9px;padding:9px 12px;
      color:inherit;text-decoration:none;font-size:13px}
.лдок:hover{background:var(--panel)}
.лдок .тип{font-size:11.5px;color:var(--muted);font-weight:600}
.лдок .имя{font-weight:500}
.лдок .имя .мелко{font-size:11px;color:var(--muted);font-weight:400;margin-left:6px}
.лдок .сумма{font-variant-numeric:tabular-nums;font-size:12.5px;color:var(--muted)}
.лдок .сост{font-size:12px;color:var(--muted)}
.лдок .сост.оплачен{color:var(--done-ink);font-weight:500}
.лдок .сост.ждём{color:var(--wait-ink);font-weight:500}
/* Отменённый документ остаётся в списке - номер выдан, и знать о нём надо, -
   но глазами по нему не ищут. */
.лдок.отменён .имя,.лдок.отменён .сумма{color:var(--muted);text-decoration:line-through}

@media (max-width:1000px){
  .лзапись{grid-template-columns:minmax(0,1fr);row-gap:1px}
  .лдок{grid-template-columns:minmax(0,1fr) auto;row-gap:2px}
  .лдок .тип{grid-column:1}
  .лдок .сумма,.лдок .сост{grid-column:2;text-align:right}
}

/* Этап - одной строкой и одним ответом словами вместо четырёх колонок дат. */
.лэтапы{background:var(--panel);border:1px solid var(--line);border-radius:12px;overflow:hidden}
.лстрока{display:grid;grid-template-columns:30px 1fr 104px 190px;gap:10px;align-items:center;
         padding:10px 14px;border-top:1px solid var(--line);font-size:13.5px}
.лстрока:first-child{border-top:0}
.лстрока .номер{color:var(--muted);font-size:11.5px;font-weight:600}
.лстрока .срок{font-variant-numeric:tabular-nums;color:var(--muted);font-size:12.5px}
.лстрока .словами{font-size:12.5px;color:var(--muted)}
.лстрока.done .имя{color:var(--muted)}
.лстрока.done .словами{color:var(--done-ink)}
/* Закрыт, но позже срока: факт, а не тревога. Зелёным он читался бы как
   «успели», красным - как «горит»; ни то, ни другое уже не так. */
.лстрока.поздно .имя{color:var(--muted)}
.лстрока.поздно .словами{color:var(--late-ink)}
.лстрока.now{background:var(--now-soft)}
.лстрока.now .словами{color:var(--now-ink);font-weight:500}
.лстрока.late .словами{color:var(--late);font-weight:600}
.лстрока.wait{background:var(--wait-soft)}
.лстрока.wait .словами{color:var(--wait-ink);font-weight:500}

@media (max-width:1000px){
  .лстрока{grid-template-columns:26px 1fr;row-gap:2px}
  .лстрока .срок,.лстрока .словами{grid-column:2}
}

/* Привязка документа к файлу в Google. Живёт в выпадении рядом с «отправить
   на согласование»: нужна она редко - только когда документ отнесли в Google
   руками, - а место рядом с главной кнопкой занимала бы всегда. */
.выпадение.широкое{min-width:22rem;padding:12px}
.выпадение .привязка{display:flex;flex-direction:column;gap:8px}
.выпадение .привязка label{font-size:12px}
.выпадение .привязка input{width:100%}
.выпадение .привязка button{width:auto;text-align:center}

/* Подписанный экземпляр, который вернул клиент. Блок на карточке документа:
   файл лежит для истории, из него ничего не собирается. */
.скан-клиента{padding:14px 16px;margin-bottom:14px}
.скан-клиента input[type=file]{width:auto;max-width:22rem}

/* Кадры материала. Плитка с автоподбором числа колонок: кадров бывает и
   пять, и сто, а задавать их число руками - значит промахнуться на первом
   же экране другой ширины. Картинка кликается в полный размер. */
.кадры{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px}
.кадры img{width:100%;height:auto;display:block;border-radius:6px;border:1px solid var(--line2)}
.кадры a:hover img{border-color:var(--accent)}

/* Отбор в материалах: строка поиска и два выпадающих списка в один ряд.
   Общая `.кбпоиск` рассчитана на поле с кнопкой, и `select` в ней растягивался
   во всю ширину - ряд разъезжался на три строки. */
.отбор{display:flex;gap:8px;align-items:center;margin-bottom:12px;flex-wrap:wrap}
.отбор input[type=search]{flex:1;min-width:14rem;max-width:26rem}
.отбор select{width:auto;min-width:11rem;max-width:16rem}
.отбор button{width:auto}

/* Разбор встречи в строке списка записей: три строки мелким, дальше
   многоточие. Без него все встречи в списке называются одинаково. */
.мелко-серо{font-size:.78rem;color:var(--muted);margin:3px 0;max-width:62ch;
            display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;
            overflow:hidden}

/* Переименование прямо в строке списка. Карандаш проявляется на наведении:
   стоять открыто в каждой строке ему незачем - имя правят один раз, а
   мозолит глаза он всегда. На тачскрине наведения нет, поэтому там он виден
   сразу, иначе до него просто не добраться. */
.имя-строки{display:flex;align-items:center;gap:6px}
.имя-строки>.переименование>summary{opacity:0;padding:1px 6px;line-height:1.4}
tr:hover .имя-строки>.переименование>summary,
.имя-строки>.переименование[open]>summary,
.имя-строки>.переименование>summary:focus-visible{opacity:1}
@media (hover:none){.имя-строки>.переименование>summary{opacity:1}}
.переименование .выпадение{min-width:22rem;padding:10px}
.переименование .выпадение form{display:flex;flex-direction:column;gap:8px}
.переименование .выпадение input[type=text]{width:100%}
.переименование .выпадение button{width:auto;align-self:flex-start;text-align:center}

/* В ряду отбора бывает не одна форма, а две: отбор и действие рядом с ним.
   Вложить вторую в первую нельзя - браузер выбрасывает внутренний тег, и её
   кнопка молча становится кнопкой внешней формы. */
.отбор>form{display:flex;gap:8px;align-items:center;margin:0;flex-wrap:wrap}

/* Панели вкладки «Работа» на карточке проекта. Свой отступ снизу у `article`
   внутри сетки давал бы двойной зазор: расстояние между панелями задаёт сама
   сетка. */
.лдва>article{margin:0}
.лсводка .h5{display:block;margin-bottom:4px}

/* Ссылки проекта: сверху своё (бриф, ТЗ) - сервис знает о них сам, снизу
   внешнее, что вписали руками. Разные по происхождению, поэтому и выглядят
   по-разному: у своих не бывает крестика, их не отвязывают. */
.лссылка.своя{background:var(--accent-soft);border-color:transparent}
.лссылка.своя a{color:var(--accent-ink)}
.лссылка.своя.пусто{background:var(--grid)}
.лссылка.своя.пусто a{color:var(--muted)}
/* Чаты, доступы и ссылки над вкладками карточки проекта. Ссылка проекта
   заводится из свёрнутой строки в том же ряду: форма на виду всё время
   занимала бы место, а нужна раз в месяц. */
.лдоступы{margin:10px 0 14px}
.лдоступы .доступы{margin-top:4px}
.лсвоя-ссылка{display:inline-block}
.лсвоя-ссылка>summary{list-style:none;cursor:pointer;color:var(--muted);
                      border-style:dashed;padding:3px 10px}
.лсвоя-ссылка>summary::-webkit-details-marker{display:none}
.лсвоя-ссылка[open]>summary{color:var(--ink)}
.лсвоя-ссылка .лновое{margin-top:6px}

/* Часть встречи в списке записей Zoom. Слева полоса: строки одной встречи
   стоят подряд, и без неё непонятно, что это одна конференция, разрезанная
   на записи, а не три разные встречи подряд. */
.tblcard tr.часть td:first-child{box-shadow:inset 3px 0 0 var(--wait)}

/* Свёрнутая форма прямо под другой формой: «клиента нет в списке — завести».
   Не выпадающее меню - ему тут некуда падать, и разворачиваться оно должно
   на месте, сдвигая то, что ниже. */
.меню-встык{margin-top:12px}
.меню-встык>summary{list-style:none;cursor:pointer;display:inline-flex}
.меню-встык>summary::-webkit-details-marker{display:none}
.меню-встык[open]>summary{border-color:var(--accent);color:var(--accent-ink)}
.меню-встык>small{display:block;margin-top:4px;line-height:1.45}

/* Доступы к кабинетам клиента. Строка: от чего доступ, логин с паролем и
   крестик. Пароля в разметке нет - на его месте кнопка, которая спрашивает
   его отдельным запросом. */
.доступы{display:flex;flex-direction:column}
.доступ{display:grid;grid-template-columns:minmax(0,1fr) auto auto;gap:10px;
        align-items:start;padding:8px 2px;border-bottom:1px solid var(--line)}
.доступы>.доступ:last-of-type{border-bottom:0}
.доступ .что{min-width:0;font-size:13.5px}
.доступ .что .мелко{font-size:11.5px;color:var(--muted);margin-top:2px}
.доступ .строки{display:flex;flex-direction:column;gap:4px;align-items:flex-end}
.доступ .пара{display:flex;align-items:center;gap:6px}
.доступ .подпись{font-size:10.5px;text-transform:uppercase;letter-spacing:.06em;
                 color:var(--muted)}
.доступ code{font-size:12.5px;background:var(--panel2);border:1px solid var(--line);
             border-radius:6px;padding:2px 7px;cursor:pointer;max-width:18rem;
             overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.доступ code:hover{border-color:var(--line2)}
.доступ code.скопировано{background:var(--done-soft);border-color:var(--done);
                         color:var(--done-ink)}
.доступ .убрать{border:0;background:transparent;color:var(--line2);cursor:pointer;
                font-size:15px;line-height:1;padding:0 2px}
.доступ:hover .убрать{color:var(--muted)}
.доступ .убрать:hover{color:var(--late)}
/* Форма в одну строку с переносом: полей пять, и на узком окне они встают
   столбиком сами. */
.новый-доступ{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-top:10px}
.новый-доступ input{flex:1 1 9rem;min-width:0;max-width:16rem}
.новый-доступ input[name=title]{flex:2 1 13rem}
.новый-доступ button{flex:0 0 auto}

/* Правка полей собранного документа. Поля узкие: в них номера счетов, суммы
   и короткие строки, а не абзацы, - растянутые на всю ширину они читались бы
   как форма заведения документа заново. */
.поля-правка{display:grid;grid-template-columns:repeat(auto-fill,minmax(19rem,1fr));
             gap:8px 14px;margin-top:10px}
.поля-правка label{display:flex;flex-direction:column;gap:3px;margin:0}
.поля-правка .имя{font-size:10.5px;letter-spacing:.04em;color:var(--muted);
                  font-family:ui-monospace,Menlo,Consolas,monospace}
.поля-правка input{width:100%;font-size:13px}
/* Считаемое показано, но не правится: сумма прописью производная от цифр. */
.поля-правка label.считается input{background:var(--panel2);color:var(--muted)}
.поля-правка .form-actions{grid-column:1/-1;margin-top:4px}

/* Предложенные статьи базы знаний. Строка: галочка, название с разделом,
   зачем это годится, и текст под раскрытием - абзацы в списке не правят, их
   правят уже на самой статье. */
.кбпредложение{display:flex;gap:10px;align-items:flex-start;padding:10px 2px;
               border-bottom:1px solid var(--line)}
.кбпредложение:last-of-type{border-bottom:0}
.кбпредложение .галочка{flex:0 0 auto;margin:5px 0 0}
.кбпредложение .галочка input{width:17px;height:17px}
.кбпредложение .что{flex:1;min-width:0}
.кбпредложение .строка{display:flex;gap:8px;flex-wrap:wrap}
.кбпредложение .строка input[type=text]{flex:1 1 20rem;min-width:0;max-width:34rem}
.кбпредложение .строка input[name^="раздел"]{flex:0 1 13rem;max-width:13rem}
.кбпредложение .зачем{font-size:12px;color:var(--muted);margin-top:4px;line-height:1.45}
.кбпредложение .текст{margin-top:6px}
.кбпредложение .текст summary{cursor:pointer;font-size:12px;color:var(--accent-ink);
                              list-style:none;display:inline-flex}
.кбпредложение .текст summary::-webkit-details-marker{display:none}
.кбпредложение .текст summary:hover{text-decoration:underline}
.кбпредложение .текст .proza{margin-top:6px;padding:10px 12px;background:var(--panel2);
                             border-radius:9px;font-size:13px;white-space:pre-wrap;
                             max-height:22rem;overflow:auto}

/* Задачи: переключатель «список - канбан» на вкладке «Сегодня» и сам канбан
   по статусам. Колонки равной ширины: их три, и прокрутка вбок здесь не
   нужна. На узком окне встают столбиком. */
.звид{display:inline-flex;gap:2px;background:var(--grid);border-radius:8px;padding:2px;margin:4px 0 10px}
.звид a{padding:4px 12px;border-radius:6px;font-size:12.5px;color:var(--muted);text-decoration:none}
.звид a.on{background:var(--panel);color:var(--ink);box-shadow:0 1px 2px var(--тень)}
.зканбан{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}
@media (max-width:700px){.зканбан{grid-template-columns:minmax(0,1fr)}}
.зколонка{background:var(--grid);border-radius:11px;padding:9px;min-height:140px;
          border:2px solid transparent}
.зколонка.цель{border-color:var(--accent-soft)}
.зколонка.над{border-color:var(--accent);background:var(--accent-soft)}
.зколонка-шапка{font-size:11px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
                color:var(--muted);margin:0 2px 8px}
.зколонка-шапка span{color:var(--ink);margin-left:4px}
.зкарта{background:var(--panel);border:1px solid var(--line);border-radius:8px;
        padding:8px 9px;margin-bottom:6px}
.зкарта[draggable=true]{cursor:grab}
.зкарта.едет{opacity:.45}
.зкарта.поздно{border-left:3px solid var(--late)}
.зкарта .имя{display:block;width:100%;text-align:left;border:0;background:none;padding:0;
             font:inherit;font-size:13.5px;color:var(--ink);cursor:pointer}
.зкарта .метки{display:flex;flex-wrap:wrap;gap:4px;align-items:center;margin-top:6px}
.зкарта .круг{width:10px;height:10px;flex:0 0 10px;margin:0}
.выполненные.поручил{margin:6px 0 10px}

/* Стоящий таймер шага объясняет, почему стоит. Не серым: серое читалось как
   «сломалось». */
.часы .стоит{margin-top:6px;font-size:12.5px;color:var(--wait-ink);background:var(--wait-soft);
             border-radius:6px;padding:4px 8px;display:inline-block}

/* База знаний: переключатель ролей над статьёй, части для ролей, выбор ролей
   при публикации и тест. */
.кбролиполоса{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin:8px 0 10px}
.кбролиполоса .chip{cursor:pointer;border:1px solid var(--line);background:var(--panel)}
.кбролиполоса .chip.on{background:var(--accent);border-color:var(--accent);color:#fff}
.кброль{border-left:3px solid var(--accent-soft);padding-left:12px;margin:10px 0}
.кброль[hidden]{display:none}
.кброль-для{font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);margin-bottom:4px}
.кброли-выбор{display:flex;flex-wrap:wrap;gap:6px;align-items:center}
.кброли-выбор .chip{display:inline-flex;gap:5px;align-items:center;cursor:pointer}
.кбтест fieldset{margin:0 0 10px;border:1px solid var(--line)}
.кбтест fieldset.неверно{border-color:var(--late)}
.кбтест legend{font-weight:600;padding:0 4px;text-transform:none;letter-spacing:0;font-size:15px;color:var(--ink)}
.кбвариант{display:flex;gap:8px;align-items:flex-start;margin:6px 0;font-weight:normal;cursor:pointer}
.кбвариант input{width:auto;margin-top:3px}
textarea.моно{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:13px}

/* Метка направления цветом направления (у каждого свой, правится на экране
   направлений). Цвет букв считает сервис по яркости фона. */
.метка.цветная{background:var(--фон);color:var(--буквы);border-color:var(--фон)}
.метка.цветная.личное{border-style:solid}
button.метка.цветная:hover{filter:brightness(1.08)}
