/* СОБРАНО tools/build-css.mjs из frontend/styles/index.css (496 файлов).
   НЕ ПРАВИТЬ ВРУЧНУЮ: изменения вносятся в исходные файлы, затем
   node tools/build-css.mjs. Порядок файлов = порядок @import. */
/* ==== base.001.css ==== */
/* ============================================================
   ToDoList — design tokens
   ============================================================ */
:root{
  color-scheme:light;

  /* --- акцент ------------------------------------------------ */
  /* Редизайн: тот же фирменный фиолетовый (оттенок сохранён), но
     сбавлена насыщенность и подняты тинты. Прежний #5B50F0 —
     почти неоновый: на белом он «звенит» и требует внимания
     всегда, из-за чего акцентом переставало быть что-либо
     конкретное. Сейчас цвет спокойнее и работает как отметка
     важного, а не как фон интерфейса. */
  --accent:#5B4FDB;
  --accent-600:#4C40C9;
  --accent-700:#3F35A8;
  --accent-soft:#F0EEFC;
  --accent-soft-2:#F8F7FE;
  --accent-line:#DFDBF7;
  --accent-ring:rgba(91,79,219,.14);
  --accent-fg:#ffffff;
  --coral:#f06a6a;
  /* Текст/иконка поверх насыщенной заливки (кнопка danger, полоса
     прогресса, аватар, плашка выделения) — одно и то же белое во
     обеих темах, раньше было прописано #fff в 20+ местах порознь. */
  --on-solid:#fff;
  --star:#e6a92b;

  /* --- текст: четыре ступени контраста ------------------------ */
  /* Второстепенные ступени намеренно светлее прежних: подпись
     колонки и счётчик не должны спорить с названием задачи. */
  --ink:#1A1C23;
  --ink-2:#454852;
  --muted:#6C7080;
  --faint:#8A8E9C;

  /* --- поверхности: от «хрома» вниз к поднятым карточкам ------ */
  /* Рабочая область стала белой, а не сероватой: основной контент
     должен визуально доминировать, а «хром» — отступать. Разница
     между слоями теперь минимальная и держится на границах,
     а не на заливках разной темноты. */
  --chrome:#E8E8EB;      /* рейка — самый нижний слой */
  --chrome-2:#ECECF0;    /* боковая панель */
  --canvas:#ECECF0;      /* рабочая область */
  --well:#E5E5EB;        /* утопленные ёмкости: колонки доски, поля */
  --surface:#F0F0F3;     /* карточки */
  --surface-2:#E5E5EB;   /* поля ввода, второстепенные плашки */
  --surface-3:#DCDCE2;   /* наведение на плотных списках */
  --raised:#F0F0F3;      /* меню, модальные окна */

  --line:#CECFD5;
  --line-2:#E5E5EB;
  --line-3:#BDBDE6;
  --edge-hi:rgba(0,0,0,.05);   /* световая кромка сверху */
  --glass:rgba(245,245,247,.82);

  /* --- глубина: тень как исключение, а не фон ------------------ */
  /* Раньше почти каждый элемент нёс двухслойную тень; вместе они
     давали то самое ощущение «панели администратора», где всё
     приподнято и ничто не выделено. Тени ослаблены до едва
     заметных, а роль разделителя передана тонкой границе —
     она честнее показывает край и не мутит белое поле. */
  --shadow-xs:0 1px 1px rgba(24,26,34,.025);
  --shadow-sm:0 1px 2px rgba(24,26,34,.04);
  --shadow:0 1px 3px rgba(24,26,34,.05);
  --shadow-md:0 4px 12px -3px rgba(24,26,34,.08);
  --shadow-lg:0 8px 28px -8px rgba(24,26,34,.13);
  --shadow-panel:-1px 0 0 var(--line),-18px 0 44px -28px rgba(24,26,34,.16);
  --ring:0 0 0 3px var(--accent-ring);

  /* --- семантика ---------------------------------------------- */
  /* Тинты подняты ближе к белому: в списке из полусотни строк
     плашки статуса и приоритета стоят подряд, и прежние плотные
     заливки складывались в рябь. Цвет по-прежнему различает
     значения, но перестал соревноваться с текстом задачи. */
  --ok:#0B7A55; --ok-soft:#EAF7F1; --ok-line:#C6E8D9;
  --warn:#93590A; --warn-soft:#FDF4E4; --warn-line:#F0DDB4;
  --danger:#BB2E24; --danger-soft:#FDEDEB; --danger-line:#F5CFCA;
  --info:#1A5FB8; --info-soft:#ECF3FC; --info-line:#CCDFF7;
  /* «Яркий» акцент — заметно светлее и насыщеннее основного --ok/
     --warn/--danger/--info, специально для мелких значков и плашек
     на мягком (…-soft) фоне: там основной, приглушённый цвет (для
     AA-контраста на сплошной заливке) выглядит тускло. Раньше эти
     четыре оттенка были прописаны хексом в шести разных местах кода
     — один и тот же цвет, просто не названный. У тёмной темы своих
     значений не было вовсе, из-за чего плашки одобрения и гостевая
     метка молча оставались светлотемными даже в тёмном интерфейсе. */
  --ok-strong:#16a06a; --warn-strong:#e0902a; --danger-strong:#e0483d; --info-strong:#2a7de0;

  /* --- радиусы ------------------------------------------------ */
  /* Редизайн: шкала сжата и выровнена. Прежние 16/22/28px на
     карточках и модальных окнах читались как шаблон дашборда —
     чем крупнее блок, тем сильнее он был скруглён, и форма
     начинала говорить громче содержимого. Теперь разброс
     умеренный: угол обозначает край, а не украшает его. */
  --r-xs:4px; --r-sm:6px; --r-md:8px; --r-lg:10px; --r-xl:12px; --r-2xl:14px;
  /* ============================================================
     ШКАЛА ЭЛЕМЕНТОВ УПРАВЛЕНИЯ (единая дизайн-система)
     Радиусы и цвета уже были токенами, а размеры — нет: каждый
     элемент задавал себе высоту через собственные вертикальные
     отступы. Из-за этого кнопка и чип, стоящие в одной панели,
     получались разной высоты, а поле ввода оказывалось на восемь
     пикселей выше кнопки рядом с ним — в форме они не вставали на
     одну линию. Три фиксированные высоты вместо отступов «на глаз»:
     любой элемент управления теперь принадлежит одной из трёх
     ступеней и выравнивается с любым другим той же ступени.
     --r-ctl — общий радиус для всего, что нажимают или заполняют:
     кнопка рядом с полем должна иметь такой же угол, иначе пара
     читается как два разных элемента.
     --r-pill — для меток-таблеток; раньше это было 20px, 26px и
     999px в разных местах, то есть три разных «круглых». */
  --ctl-h-sm:28px; --ctl-h:34px; --ctl-h-lg:40px;
  --r-ctl:6px; --r-pill:999px;

  /* --- шкала кегля -------------------------------------------- */
  /* ============================================================
     ТИПОГРАФИЧЕСКАЯ ШКАЛА (читаемость)
     Токены существовали, но интерфейс их почти не использовал:
     462 размера были вписаны числом прямо в правила, и среди них
     оказалось четыре ступени в пределах полутора пикселей —
     11, 11.5, 12 и 12.5. Глаз такую разницу не различает, а вот
     ритма из-за неё не возникает: подписи одного уровня выглядят
     чуть-чуть разными без всякого смысла, и иерархия читается как
     шум. Неразличимые ступени схлопнуты в одну, размеры берутся
     только из шкалы — восемь ступеней вместо двадцати. */
  --t-display:22px; --t-h1:18px; --t-lg:16px; --t-h2:15px; --t-h3:14px;
  --t-body:13.5px; --t-sm:12.5px; --t-xs:11.5px; --t-micro:10.5px;

  /* --- метрика ------------------------------------------------ */
  /* Больше воздуха по горизонтали, ниже шапка: контент начинается
     раньше и стоит свободнее. Заголовок страницы уменьшен с 28px
     до 22px — на 13-пиксельном тексте разница в 28px читалась как
     обложка, а не как название раздела. */
  --sidebar-w:260px;
  --sidebar-w-collapsed:64px;
  --rail-w:0px;
  --topbar-h:56px;
  --gutter:32px;

  --mono:'JetBrains Mono',ui-monospace,'SF Mono',Menlo,Consolas,monospace;
  --sans:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
}
/* ==== utilities.001.css ==== */
[data-theme="dark"]{
  color-scheme:dark;

  --accent:#8B7DF5;
  --accent-600:#9C90FF;
  --accent-700:#B0A6FF;
  --accent-soft:rgba(139,125,245,.15);
  --accent-soft-2:rgba(139,125,245,.08);
  --accent-line:rgba(139,125,245,.28);
  --accent-ring:rgba(139,125,245,.22);
  --accent-fg:#0B0C12;
  --coral:#f06a6a;

  --ink:#EDEFF5;
  --ink-2:#C2C6D4;
  --muted:#9BA0B2;
  --faint:#7F8497;

  --chrome:#0C0D11;
  --chrome-2:#101116;
  --canvas:#15161C;
  --well:#121319;
  --surface:#1A1C23;
  --surface-2:#20222A;
  --surface-3:#282A34;
  --raised:#1D1F26;

  --line:#282B34;
  --line-2:#1F222A;
  --line-3:#3A3E4C;
  --edge-hi:rgba(255,255,255,.045);
  --glass:rgba(21,22,28,.76);

  --shadow-xs:0 1px 1px rgba(0,0,0,.22);
  --shadow-sm:0 1px 2px rgba(0,0,0,.3);
  --shadow:0 1px 3px rgba(0,0,0,.34);
  --shadow-md:0 4px 14px -3px rgba(0,0,0,.45);
  --shadow-lg:0 10px 32px -8px rgba(0,0,0,.55);
  --shadow-panel:-1px 0 0 var(--line),-20px 0 48px -28px rgba(0,0,0,.6);

  --ok:#2ECC8F; --ok-soft:rgba(46,204,143,.14); --ok-line:rgba(46,204,143,.3);
  --warn:#E8A33D; --warn-soft:rgba(232,163,61,.14); --warn-line:rgba(232,163,61,.3);
  --danger:#FF6B5E; --danger-soft:rgba(255,107,94,.14); --danger-line:rgba(255,107,94,.3);
  --info:#5AA0F5; --info-soft:rgba(90,160,245,.14); --info-line:rgba(90,160,245,.3);
  /* В тёмной теме собственные --ok/--warn/--danger/--info уже сами по
     себе яркие и насыщенные (подобраны для контраста на тёмной
     поверхности) — отдельного, ещё более яркого варианта для значков
     здесь не нужно, тот же цвет годится и там, и там. */
  --ok-strong:var(--ok); --warn-strong:var(--warn); --danger-strong:var(--danger); --info-strong:var(--info);
}
/* ==== base.002.css ==== */
/* ============================================================ base */
*{box-sizing:border-box;margin:0;padding:0}

html,body{height:100%}

/* ============================================================
   ЗАЩИТА ОТ ГОРИЗОНТАЛЬНОГО ВЫХОДА (mobile-first)
   Базовые правила чисты — ни одной фиксированной ширины больше
   телефонного экрана, а таймлайн и доска прокручиваются внутри
   себя. Но в приложении с сотнями блоков достаточно одного
   длинного слова без пробелов (ссылка в комментарии, имя файла,
   вставленный токен), чтобы растянуть страницу и включить
   горизонтальную прокрутку всего экрана — а на телефоне это
   ощущается как поломка: содержимое уезжает, шапка съезжает,
   вернуться назад непонятно как. Здесь страховка на уровне
   страницы. Именно `clip`, а не `hidden`: `hidden` создаёт
   контекст прокрутки и ломает position:sticky у шапок таблиц
   и заголовков разделов, `clip` — нет. */
html,body{overflow-x:clip;max-width:100%}
/* ==== utilities.002.css ==== */
#main{overflow-x:clip}
/* ==== components.001.css ==== */
/* Длинные неразрывные строки переносятся, а не распирают блок. */
.task-name,.pc-name,.arc-name,.trash-name,.doc-row-title,
.cm-text,.msg-text,.rich-body,.guide-doc,.field-input{overflow-wrap:anywhere}
/* ==== base.003.css ==== */
body{
  font-family:var(--sans);
  background:var(--chrome);
  color:var(--ink);
  font-size:var(--t-body);
  line-height:1.5;
  letter-spacing:-.006em;
  font-feature-settings:'cv05' 1,'cv11' 1,'ss03' 1;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  text-rendering:optimizeLegibility;
  overflow:hidden;
}
/* ==== components.002.css ==== */
button{font-family:inherit;cursor:pointer;border:none;background:none;color:inherit}

input,textarea,select{font-family:inherit;font-size:inherit;color:inherit}
/* ==== base.004.css ==== */
::selection{background:var(--accent-soft);color:var(--accent-700)}
/* ==== utilities.003.css ==== */
[data-theme="dark"] ::selection{color:var(--ink)}

.mono{font-family:var(--mono);font-variant-numeric:tabular-nums;letter-spacing:-.01em}

svg{display:block}
/* ==== base.005.css ==== */
/* тонкие полосы прокрутки — не отвлекают от содержимого */
::-webkit-scrollbar{width:11px;height:11px}

::-webkit-scrollbar-track{background:transparent}

::-webkit-scrollbar-thumb{background:var(--line-3);border-radius:var(--r-pill);border:3.5px solid transparent;background-clip:content-box}

::-webkit-scrollbar-thumb:hover{background:var(--faint);background-clip:content-box}

*{scrollbar-width:thin;scrollbar-color:var(--line-3) transparent}
/* ==== utilities.004.css ==== */
/* видимый фокус с клавиатуры на всех интерактивных элементах */
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--r-xs)}

.hide{display:none!important}

/* ============================================================ app shell */
#app{display:grid;grid-template-columns:var(--sidebar-w) 1fr;height:100vh;background:var(--chrome);transition:grid-template-columns var(--dur) cubic-bezier(.4,0,.2,1)}

#app.collapsed{grid-template-columns:var(--sidebar-w-collapsed) 1fr}

/* рабочая область — самый светлый план, отделён от «хрома» скруглением и тенью */
.workspace{display:flex;flex-direction:column;min-width:0;height:100vh;background:var(--canvas);position:relative;z-index:1}

@media(min-width:769px){
  .workspace{
    margin:0;border-left:1px solid var(--line);
    box-shadow:-1px 0 0 var(--edge-hi),-18px 0 40px -24px rgba(15,16,32,.28);
  }
  [data-theme="dark"] .workspace{box-shadow:-1px 0 0 rgba(255,255,255,.03),-18px 0 44px -22px rgba(0,0,0,.7)}
}

.content-scroll{flex:1;overflow-y:auto;overflow-x:hidden}
/* ==== layout.001.css ==== */
/* ============================================================ sidebar */
#sidebar{
  background:var(--chrome-2);
  display:flex;flex-direction:column;
  min-width:0;overflow:hidden;
}
/* ==== utilities.005.css ==== */
.side-head{display:flex;align-items:center;gap:10px;height:var(--topbar-h);padding:0 16px 0 14px;flex-shrink:0}

.brand{display:flex;align-items:center;gap:10px;min-width:0;cursor:pointer}

.brand-mark{width:28px;height:28px;flex-shrink:0;color:var(--accent);object-fit:contain;border-radius:var(--r-sm)}

.brand-name{font-weight:700;font-size:var(--t-h2);letter-spacing:-.03em;white-space:nowrap;color:var(--ink)}

.collapsed .brand-name{opacity:0;width:0}

.side-collapse{margin-left:auto;width:28px;height:28px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;color:var(--faint);flex-shrink:0;transition:var(--dur-fast)}

.side-collapse:hover{background:var(--surface-3);color:var(--ink)}

.collapsed .side-collapse{margin-left:0}

.side-create{margin:6px 12px 8px}
/* ==== components.003.css ==== */
.btn-create{
  width:100%;display:flex;align-items:center;gap:9px;
  background:var(--accent);color:var(--accent-fg);font-weight:600;font-size:var(--t-body);
  height:var(--ctl-h-lg);padding:0 13px;border-radius:var(--r-ctl);
  box-shadow:var(--shadow-sm),inset 0 1px 0 rgba(255,255,255,.18);
  transition:background var(--dur-fast),transform var(--dur-instant);white-space:nowrap;
}

.btn-create:hover{background:var(--accent-600)}

.btn-create:active{transform:scale(.98)}

.btn-create svg{flex-shrink:0}

.collapsed .btn-create{justify-content:center;padding:9px 0}

.collapsed .btn-create .lbl{display:none}
/* ==== layout.002.css ==== */
.side-nav{flex:1;overflow-y:auto;padding:2px 10px 14px}

.side-nav::-webkit-scrollbar{width:8px}

.nav-item{
  display:flex;align-items:center;gap:11px;
  padding:8px 10px;border-radius:var(--r-sm);
  color:var(--ink-2);font-weight:500;font-size:var(--t-body);
  white-space:nowrap;position:relative;user-select:none;
  transition:background var(--dur-instant),color var(--dur-instant);
}

/* Раздел «визуальная полировка»: защита от переполнения длинным
   текстом. Сейчас ни одна подпись пункта меню не переполняется ни
   на одном из трёх языков (измерено scrollWidth/clientWidth), но
   .lbl был не защищён архитектурно — полагался только на то, что
   текущие переводы случайно достаточно короткие. min-width:0
   позволяет flex-элементу сжаться меньше своего содержимого (без
   этого overflow/ellipsis не сработали бы в flex-контейнере вовсе),
   text-overflow:ellipsis аккуратно обрезает, а не выталкивает текст
   за границу сайдбара — особенно важно для названий проектов
   (пользовательский контент произвольной длины), не только для
   системных подписей меню. */
.nav-item .lbl,.proj-item .lbl{overflow:hidden;text-overflow:ellipsis;min-width:0;flex:1}

.nav-item svg{flex-shrink:0;width:18px;height:18px;color:var(--faint);transition:color var(--dur-instant)}

.nav-item:hover{background:var(--surface-3);color:var(--ink)}

.nav-item:hover svg{color:var(--muted)}

.nav-item.active{
  background:var(--surface);color:var(--ink);font-weight:600;
  box-shadow:var(--shadow-xs),inset 0 1px 0 var(--edge-hi);
}

.nav-item.active svg{color:var(--accent)}

[data-theme="dark"] .nav-item.active{background:var(--surface-2)}

.nav-item .badge{margin-left:auto;background:var(--accent);color:var(--accent-fg);font-size:var(--t-micro);font-weight:700;min-width:19px;height:19px;padding:0 6px;border-radius:var(--r-pill);display:flex;align-items:center;justify-content:center;font-variant-numeric:tabular-nums}

.nav-item.active .badge{background:var(--accent)}

.collapsed .nav-item .lbl,.collapsed .nav-item .badge{display:none}

.collapsed .nav-item{justify-content:center;padding:9px 6px;margin:0 4px;border-radius:var(--r-sm)}

.nav-section{margin-top:16px}

.nav-label{
  display:flex;align-items:center;gap:6px;
  padding:6px 10px 4px;font-size:var(--t-xs);font-weight:600;
  color:var(--faint);
  white-space:nowrap;
}

.nav-label .add{margin-left:auto;width:22px;height:22px;border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;color:var(--faint);transition:var(--dur-instant)}

.nav-label .add:hover{background:var(--surface-3);color:var(--ink)}

.collapsed .nav-label{justify-content:center;font-size:0;padding:8px 0 2px}

.collapsed .nav-label .txt{display:none}

.collapsed .nav-label .add{display:none}
/* ==== utilities.006.css ==== */
.proj-item{display:flex;align-items:center;gap:11px;padding:8px 10px;border-radius:var(--r-sm);color:var(--ink-2);font-weight:500;font-size:var(--t-body);white-space:nowrap;cursor:pointer;transition:background var(--dur-instant),color var(--dur-instant)}

/* Иконки внутри .proj-item — постоянного размера через CSS, а не то,
   какой параметр передали в ic() по месту вызова: раньше значок
   портфеля в «Избранном» получался 14px, хотя всё остальное в
   sidebar — 18px, и это было просто то, что написал в одном
   конкретном месте, а не осознанное решение. */
.proj-item svg{flex-shrink:0;width:16px;height:16px;color:var(--faint)}

/* Оптимизация для больших пространств (десятки тысяч проектов): тот же приём, что уже проверен и измерен для строк списка задач — браузер сам пропускает раскладку и отрисовку для элементов вне видимой области. */
.proj-item{content-visibility:auto;contain-intrinsic-size:0 35px}

.proj-item:hover{background:var(--surface-3);color:var(--ink)}

.proj-item.active{background:var(--surface);color:var(--ink);font-weight:600;box-shadow:var(--shadow-xs),inset 0 1px 0 var(--edge-hi)}

[data-theme="dark"] .proj-item.active{background:var(--surface-2)}

.proj-dot{width:12px;height:12px;border-radius:var(--r-xs);flex-shrink:0;box-shadow:inset 0 0 0 1px rgba(0,0,0,.08)}

.collapsed .proj-item .lbl{display:none}

.collapsed .proj-item{justify-content:center;padding:8px 0}

.side-foot{border-top:1px solid var(--line);padding:8px 10px;flex-shrink:0}
/* ==== layout.003.css ==== */
/* ============================================================
   ПЕРСОНАЛИЗАЦИЯ — ручка изменения ширины сайдбара
   ============================================================ */
.sidebar-resize-handle{position:fixed;top:0;bottom:0;left:var(--sidebar-w);width:6px;margin-left:-3px;cursor:col-resize;z-index:60;transition:background var(--dur-instant)}

.sidebar-resize-handle:hover{background:var(--accent-line)}

#app.collapsed .sidebar-resize-handle{display:none}
/* ==== utilities.007.css ==== */
@media (max-width:768px){.sidebar-resize-handle{display:none}}
/* ==== components.004.css ==== */
/* ============================================================
   ПЕРСОНАЛИЗАЦИЯ — настройки
   ============================================================ */
/* ============================================================
   UX-АУДИТ — баннер «фильтр скрывает все задачи»
   ============================================================ */
/* ============================================================
   ПОЛИРОВАННОЕ ПОДТВЕРЖДЕНИЕ
   ============================================================ */
.btn-danger{background:var(--danger);color:var(--on-solid);border:1px solid var(--danger)}

.btn-danger:hover{filter:brightness(.93)}
/* ==== utilities.008.css ==== */
.cm-confirm-text{font-size:var(--t-body);line-height:1.6;color:var(--ink-2);margin:0}

.filtered-empty-banner{display:flex;align-items:center;gap:10px;padding:12px 16px;margin:0 0 14px;background:var(--warn-soft);border:1px solid var(--warn-line,var(--line));border-radius:var(--r-md);color:var(--ink-2);font-size:var(--t-body)}

/* ============================================================
   PWA — БАННЕР ОБНОВЛЕНИЯ SERVICE WORKER
   ============================================================ */
.sw-update-banner{position:fixed;left:50%;bottom:22px;transform:translateX(-50%);z-index:900;display:flex;align-items:center;gap:12px;padding:11px 14px 11px 18px;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--shadow-lg);font-size:var(--t-body);color:var(--ink-2);animation:swBannerIn .25s cubic-bezier(.4,0,.2,1)}

.sw-update-banner span{display:flex;align-items:center;gap:7px;color:var(--accent-700)}

@keyframes swBannerIn{from{opacity:0;transform:translateX(-50%) translateY(10px)}to{opacity:1;transform:translateX(-50%) translateY(0)}}

@media (max-width:768px){.sw-update-banner{left:14px;right:14px;bottom:14px;transform:none;width:auto}
@keyframes swBannerIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}}

.filtered-empty-banner svg{flex-shrink:0;color:var(--warn)}

.filtered-empty-banner span{flex:1}

.pz-swatches{display:flex;gap:9px;align-items:center;flex-wrap:wrap}

.pz-swatch{width:30px;height:30px;border-radius:50%;border:2px solid transparent;cursor:pointer;transition:var(--dur-instant);padding:0}

.pz-swatch:hover{transform:scale(1.1)}

.pz-swatch.sel{border-color:var(--ink);box-shadow:0 0 0 2px var(--surface)}

.pz-custom-color{width:30px;height:30px;border-radius:50%;border:1px dashed var(--line-3);cursor:pointer;padding:0;background:transparent}

.pz-dash-list{display:flex;flex-direction:column;gap:6px}

.pz-row{display:flex;align-items:center;justify-content:space-between;padding:8px 10px;border:1px solid var(--line-2);border-radius:var(--r-sm);font-size:var(--t-body)}

.dash-preset-switch{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:10px}
/* ==== components.005.css ==== */
.dash-preset-btn{padding:5px 11px;border-radius:var(--r-lg);border:1px solid var(--line);background:var(--surface);color:var(--muted);font-size:var(--t-sm);cursor:pointer}

.dash-preset-btn.active{background:var(--accent);border-color:var(--accent);color:var(--on-solid)}
/* ==== utilities.009.css ==== */
.dash-drag-handle{cursor:grab;color:var(--faint);flex-shrink:0;display:flex}

.dash-settings-row{display:flex;align-items:center;gap:8px}

.dash-settings-row.dragging{opacity:.4}

.user-chip{display:flex;align-items:center;gap:10px;padding:7px 8px;border-radius:var(--r-sm);white-space:nowrap;transition:background var(--dur-instant)}

.user-chip:hover{background:var(--surface-3)}

.user-chip .meta{min-width:0;flex:1}

.user-chip .nm{font-weight:600;font-size:var(--t-body);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.user-chip .sub{font-size:var(--t-xs);color:var(--faint);letter-spacing:.01em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.collapsed .user-chip .meta,.collapsed .user-chip .caret{display:none}

.collapsed .user-chip{justify-content:center;padding:6px 0}
/* ==== components.006.css ==== */
/* avatar */
.avatar{border-radius:50%;flex-shrink:0;display:flex;align-items:center;justify-content:center;color:var(--on-solid);font-weight:600;font-size:var(--t-sm);line-height:1;background:var(--faint);user-select:none;box-shadow:inset 0 0 0 1px rgba(0,0,0,.07),inset 0 1px 0 rgba(255,255,255,.18)}

.avatar.sm{width:22px;height:22px;font-size:var(--t-micro)}

.avatar.md{width:28px;height:28px;font-size:var(--t-xs)}

.avatar.lg{width:34px;height:34px;font-size:var(--t-body)}

.avatar.xl{width:52px;height:52px;font-size:var(--t-lg)}
/* ==== utilities.010.css ==== */
/* ============================================================ topbar */
#topbar{
  height:var(--topbar-h);flex-shrink:0;
  display:flex;align-items:center;gap:14px;
  padding:0 var(--gutter) 0 20px;background:var(--canvas);
  border-bottom:1px solid var(--line-2);
}

#topbar{position:relative}
/* ==== features.001.css ==== */
.tb-search{position:absolute;left:50%;transform:translateX(-50%);width:min(560px,38vw)}
/* ==== components.007.css ==== */
.tb-search input{
  width:100%;height:36px;padding:0 12px 0 36px;
  background:var(--well);border:1px solid var(--line-2);
  border-radius:var(--r-md);font-size:var(--t-body);transition:var(--dur-fast);
}

.tb-search input::placeholder{color:var(--faint)}

.tb-search input:hover{background:var(--surface-3);border-color:var(--accent-soft)}

.tb-search input:focus{outline:none;border-color:var(--accent);background:var(--surface);box-shadow:var(--ring)}
/* ==== features.002.css ==== */
.tb-search svg{position:absolute;left:11px;top:9px;color:var(--muted);pointer-events:none}
/* ==== utilities.011.css ==== */
.tb-icon{width:34px;height:34px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;color:var(--muted);position:relative;transition:var(--dur-instant)}

/* Единый размер значка независимо от того, что указано по месту
   вызова ic(): раньше «Входящие» рисовались в 18px, а «ИИ» и «Тема»
   — в 17px, разница на глаз небольшая, но именно то «случайное»
   рассогласование, которого просили не допускать. Правило на уровне
   CSS не даёт этому повториться, даже если где-то по невнимательности
   снова передадут другое число. */
.tb-icon svg{width:18px;height:18px}

/* Переключатель языка — рядом с темой, раскрытие по наведению на
   десктопе и по клику на сенсорных экранах (:hover там не работает
   естественным образом, поэтому класс .open дублирует то же
   поведение). Порядок вариантов в разметке (langSwitcherHTML) —
   не в CSS: Türkçe → Русский → English, фиксированно, вне
   зависимости от текущего выбора. */
.tb-lang-wrap{position:relative}

.tb-lang-code{position:absolute;bottom:2px;right:2px;font-size:8.5px;font-weight:700;line-height:1;color:var(--accent-700);background:var(--surface);border-radius:3px;padding:0 2px;pointer-events:none}

.tb-lang-pop{position:absolute;top:calc(100% + 8px);right:0;min-width:148px;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-md);box-shadow:var(--shadow-lg);padding:5px;z-index:60;opacity:0;visibility:hidden;transform:translateY(-4px);transition:opacity var(--dur-fast),transform var(--dur-fast),visibility var(--dur-fast)}

.tb-lang-wrap:hover .tb-lang-pop,.tb-lang-wrap.open .tb-lang-pop{opacity:1;visibility:visible;transform:translateY(0)}

.lang-opt{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:8px 10px;border-radius:var(--r-sm);font-size:var(--t-body);color:var(--ink-2);cursor:pointer;transition:var(--dur-instant)}

.lang-opt:hover{background:var(--surface-2);color:var(--ink)}

.lang-opt.on{color:var(--accent-700);font-weight:600}

.lang-opt.on svg{color:var(--accent)}

.tb-icon:hover{background:var(--surface-3);color:var(--ink)}

.tb-icon:focus-visible{outline:none;box-shadow:var(--ring)}

.tb-icon .dot{position:absolute;top:7px;right:7px;width:7px;height:7px;border-radius:50%;background:var(--danger);border:2px solid var(--canvas)}

/* ============================================================ page header */
.page{padding:0 var(--gutter)}

/* Шапка страницы — верхняя ступень иерархии: надзаголовок моноширинным,
   крупный титул, описание. Живёт на том же плане, что и содержимое. */
.page-head{padding:26px var(--gutter) 0;background:var(--canvas)}

.page-title{font-size:var(--t-display);font-weight:700;letter-spacing:-.032em;line-height:1.15}

.page-sub{color:var(--muted);font-size:var(--t-body);margin-top:8px;max-width:70ch;line-height:1.55}

.simple-page-body{padding:22px var(--gutter) 64px}

.ph-simple-top{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;flex-wrap:wrap}

.ph-top{display:flex;align-items:flex-start;gap:16px}

.ph-title-wrap{min-width:0;flex:1}

.ph-eyebrow{
  font-size:var(--t-xs);font-weight:500;
  color:var(--faint);margin-bottom:9px;
  display:flex;align-items:center;gap:7px;
}

.ph-title{font-size:var(--t-display);font-weight:700;letter-spacing:-.032em;line-height:1.15;display:flex;align-items:center;gap:13px;min-width:0}

.ph-emoji{width:38px;height:38px;border-radius:var(--r-md);display:flex;align-items:center;justify-content:center;font-size:var(--t-lg);flex-shrink:0;box-shadow:inset 0 0 0 1px rgba(0,0,0,.05),inset 0 1px 0 rgba(255,255,255,.25)}

.ph-desc{color:var(--muted);font-size:var(--t-body);margin-top:8px;max-width:70ch;line-height:1.55}

.ph-actions{display:flex;align-items:center;gap:8px;flex-shrink:0;padding-top:4px}
/* ==== components.008.css ==== */
.avatar-stack{display:flex}

.avatar-stack .avatar{border:2px solid var(--canvas);margin-left:-8px}

.avatar-stack .avatar:first-child{margin-left:0}

.avatar-add{width:30px;height:30px;border-radius:50%;border:1.5px dashed var(--line-3);display:flex;align-items:center;justify-content:center;color:var(--faint);margin-left:-8px;background:var(--canvas);transition:var(--dur-fast)}

.avatar-add:hover{border-color:var(--accent);color:var(--accent)}

/* вкладки — подчёркивание акцентом, ровно один активный уровень */
.tabs{display:flex;gap:2px;margin-top:22px;border-bottom:1px solid var(--line);overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none}

.tabs::-webkit-scrollbar{display:none}

.tabs>*{flex:0 0 auto}

.tab{
  padding:8px 12px 11px;font-size:var(--t-body);font-weight:600;color:var(--muted);
  border-bottom:2px solid transparent;margin-bottom:-1px;transition:var(--dur-instant);
  display:flex;align-items:center;gap:7px;white-space:nowrap;border-radius:var(--r-xs) var(--r-xs) 0 0;
}

.tab svg{color:var(--faint);transition:color var(--dur-instant)}

.tab:hover{color:var(--ink)}

.tab:hover svg{color:var(--muted)}

.tab.active{color:var(--accent-700);border-bottom-color:var(--accent)}

.tab.active svg{color:var(--accent)}

[data-theme="dark"] .tab.active{color:var(--accent-600)}

/* «Ещё» — не пятое равноправное представление, а вход в остальные,
   поэтому оно намеренно тише вкладок: без иконки, обычным начертанием
   и без возможности стать активным. */
.tab-more{font-weight:500;color:var(--faint);gap:4px}

.tab-more:hover{color:var(--ink-2)}

.tab-more svg{width:12px;height:12px}
/* ==== utilities.012.css ==== */
/* Рейка — нижний слой интерфейса. Активный раздел отмечен «контуром»:
   вертикальной акцентной чертой у края экрана. */
#rail{width:var(--rail-w);flex-shrink:0;background:var(--chrome);display:flex;flex-direction:column;align-items:center;padding:12px 0;gap:2px}

.tb-create-wrap{display:flex;flex-shrink:0}

.tb-create{display:flex;align-items:center;gap:8px;height:var(--ctl-h);padding:0 13px 0 9px;background:var(--accent);color:var(--accent-fg);border:0;border-radius:var(--r-ctl) 0 0 var(--r-ctl);font:inherit;font-size:var(--t-body);font-weight:600;cursor:pointer;flex-shrink:0;box-shadow:var(--shadow-sm),inset 0 1px 0 rgba(255,255,255,.2);transition:background var(--dur-fast),transform var(--dur-instant)}

/* Стрелка рядом с «Создать»: тот же цвет, тонкая граница-разделитель,
   отдельный клик — старое меню «Проект/Цель», основная кнопка теперь
   сразу открывает форму задачи без промежуточного шага. */
.tb-create-caret{display:flex;align-items:center;justify-content:center;width:26px;height:var(--ctl-h);background:var(--accent);color:var(--accent-fg);border:0;border-left:1px solid rgba(0,0,0,.14);border-radius:0 var(--r-ctl) var(--r-ctl) 0;cursor:pointer;flex-shrink:0;margin-left:-1px;box-shadow:var(--shadow-sm),inset 0 1px 0 rgba(255,255,255,.2);transition:background var(--dur-fast)}

.tb-create-caret:hover{background:var(--accent-600)}

.tb-create-caret svg{width:13px;height:13px}

.tb-create:hover{background:var(--accent-600)}

.tb-create:active{transform:scale(.98)}

/* Тот же язык фокуса, что и у остального интерфейса (var(--ring)),
   а не общий запасной outline — раньше у этой пары не было
   собственного правила фокуса вовсе, только глобальный fallback
   с чужим радиусом, не совпадающим с формой половинки таблетки. */
.tb-create:focus-visible,.tb-create-caret:focus-visible{outline:none;box-shadow:var(--ring)}

.tb-burger:focus-visible{outline:none;box-shadow:var(--ring)}
/* ==== features.003.css ==== */
.tb-search-x:focus-visible{outline:none;box-shadow:var(--ring)}
/* ==== utilities.013.css ==== */
.tb-create-ic{width:20px;height:20px;border-radius:var(--r-xs);background:rgba(255,255,255,.2);display:flex;align-items:center;justify-content:center}

[data-theme="dark"] .tb-create-ic{background:rgba(0,0,0,.16)}

.tb-right{margin-left:auto;display:flex;align-items:center;gap:6px}

.proj-item .proj-dot{width:13px;height:13px;border-radius:var(--r-xs)}
/* ==== layout.004.css ==== */
.nav-label{font-size:var(--t-xs);font-weight:600;color:var(--faint);padding:18px 12px 6px;}
/* ==== components.009.css ==== */
.tab svg{width:16px;height:16px}

/* ============================================================ buttons */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;height:var(--ctl-h);padding:0 14px;border-radius:var(--r-ctl);font-weight:600;font-size:var(--t-body);transition:var(--dur-fast);white-space:nowrap;line-height:1.2}

.btn svg{width:16px;height:16px;flex-shrink:0}

.btn:active{transform:scale(.985)}

/* Фокус — тем же кольцом, что уже используют поля ввода (var(--ring)),
   а не отдельным цветом: одна и та же клавиатурная подсказка везде,
   не два разных языка фокуса в одном интерфейсе. */
.btn:focus-visible{outline:none;box-shadow:var(--ring)}

/* Disabled — раньше выглядела так же, как обычная кнопка, хотя уже
   реально используется в живых местах (кнопка подтверждения опасного
   действия до ввода кодового слова, отправка сообщения ИИ во время
   ответа): человек мог нажимать и не понимать, почему ничего не
   происходит. */
.btn:disabled,.btn[disabled]{opacity:.45;cursor:not-allowed;pointer-events:none;box-shadow:none;transform:none;filter:none}

.btn-primary{background:var(--accent);color:var(--accent-fg);box-shadow:var(--shadow-sm),inset 0 1px 0 rgba(255,255,255,.18)}

.btn-primary:hover{background:var(--accent-600)}

.btn-ghost{background:var(--surface);color:var(--ink-2);border:1px solid var(--line);box-shadow:var(--shadow-xs)}

.btn-ghost:hover{background:var(--surface-3);border-color:var(--line-3);color:var(--ink)}

[data-theme="dark"] .btn-ghost{background:var(--surface-2)}

[data-theme="dark"] .btn-ghost:hover{background:var(--surface-3)}

.btn-soft{background:var(--accent-soft);color:var(--accent-700)}

.btn-soft:hover{background:var(--accent-soft);filter:brightness(.97)}

[data-theme="dark"] .btn-soft{color:var(--accent-600)}

.btn-sm{height:var(--ctl-h-sm);padding:0 11px;font-size:var(--t-sm)}

.btn-icon-only{padding:0;width:var(--ctl-h);justify-content:center}
/* ==== utilities.014.css ==== */
.chip{display:inline-flex;align-items:center;gap:6px;height:var(--ctl-h-sm);padding:0 11px;border-radius:var(--r-ctl);font-size:var(--t-sm);font-weight:500;background:var(--surface);border:1px solid var(--line);color:var(--ink-2);box-shadow:var(--shadow-xs);transition:var(--dur-fast)}

.chip:hover{background:var(--surface-3);border-color:var(--line-3)}

[data-theme="dark"] .chip{background:var(--surface-2)}

[data-theme="dark"] .chip:hover{background:var(--surface-3)}

.chip svg{width:14px;height:14px;color:var(--faint)}

.chip.on{background:var(--accent-soft);border-color:var(--accent-line);color:var(--accent-700);font-weight:600;box-shadow:none}

/* «Добавить задачу» — главное действие экрана проекта, поэтому оно
   единственное на панели окрашено: рядом с ним фильтр и сортировка
   остаются нейтральными, и взгляд не выбирает между пятью
   одинаковыми серыми кнопками. */
.chip-add{background:var(--accent);border-color:var(--accent);color:var(--on-solid);font-weight:600}

.chip-add svg{color:var(--on-solid)}

.chip-add:hover{background:var(--accent-700);border-color:var(--accent-700)}

[data-theme="dark"] .chip-add{background:var(--accent);border-color:var(--accent)}

[data-theme="dark"] .chip-add:hover{background:var(--accent-600);border-color:var(--accent-600)}

.chip.on svg{color:currentColor}

[data-theme="dark"] .chip.on{color:var(--accent-600)}
/* ==== features.004.css ==== */
/* панель фильтров под вкладками */
.view-toolbar{display:flex;align-items:center;gap:8px;padding:11px var(--gutter);border-bottom:1px solid var(--line);background:var(--canvas);flex-wrap:wrap}
/* ==== utilities.015.css ==== */
.toolbar-spacer{flex:1}

/* ============================================================ LIST VIEW */
.list-wrap{padding:10px var(--gutter) 64px}

.list-colhead{display:grid;grid-template-columns:var(--list-cols,1fr 160px 130px 120px 130px 28px);gap:12px;padding:6px 12px 6px 40px;border-bottom:1px solid var(--line-2);position:sticky;top:0;background:var(--canvas);z-index:2}

/* ============================================================
   СПИСОК, А НЕ ТАБЛИЦА (дружелюбный облик)
   Заголовки колонок были набраны КАПСОМ с разрядкой и жирным —
   это визуальный код таблицы базы данных, он и создавал ощущение
   админ-панели сильнее всего остального на экране. Сам по себе
   капс ничего не сообщает: слово «Срок» читается одинаково в
   любом регистре, но в верхнем оно требует к себе внимания,
   которого заголовок служебной колонки не заслуживает. Обычный
   регистр, обычная насыщенность, приглушённый цвет — шапка
   подсказывает, а не командует. */
.list-colhead .ch{font-size:var(--t-xs);font-weight:500;color:var(--faint);letter-spacing:0;text-transform:none;position:relative}
/* ==== layout.005.css ==== */
/* Ручка изменения ширины — тонкая полоса у правого края заголовка,
   не видна в покое, чтобы не добавлять визуальный шум в спокойный
   заголовок таблицы, и подсвечивается только при наведении именно
   на неё, а не на весь заголовок колонки. */
.col-resize{position:absolute;top:-6px;right:-8px;bottom:-6px;width:9px;cursor:col-resize;z-index:3}

.col-resize::after{content:'';position:absolute;top:2px;bottom:2px;left:4px;width:2px;border-radius:1px;background:transparent;transition:background var(--dur-instant)}

.col-resize:hover::after,.col-resize.resizing::after{background:var(--accent-line)}
/* ==== utilities.016.css ==== */
.list-colhead .ch.center{text-align:center}

.section-block{margin-top:14px}

.section-head{display:flex;align-items:center;gap:8px;padding:14px 12px 8px;cursor:pointer;user-select:none}

.section-caret{width:18px;height:18px;display:flex;align-items:center;justify-content:center;color:var(--faint);transition:transform var(--dur)}

.section-block.collapsed .section-caret{transform:rotate(-90deg)}

.section-title{font-weight:700;font-size:var(--t-h3);letter-spacing:-.02em;color:var(--ink)}

.section-count{font-family:var(--mono);font-size:var(--t-xs);color:var(--faint);font-weight:500;background:var(--surface-3);padding:1px 7px;border-radius:var(--r-pill)}

.section-head .sh-actions{margin-left:auto;display:flex;gap:2px;opacity:0;transition:var(--dur-instant)}

.section-head:hover .sh-actions{opacity:1}
/* ==== components.010.css ==== */
.sh-actions button{width:26px;height:26px;border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;color:var(--faint);transition:var(--dur-instant)}

.sh-actions button:hover{background:var(--surface-3);color:var(--ink)}
/* ==== features.005.css ==== */
.section-block.collapsed .task-rows,.section-block.collapsed .add-row{display:none}

/* Строка задачи: без разлиновки — ряды разделяет воздух,
   при наведении строка «поднимается» на уровень карточки. */
.task-row{
  display:grid;grid-template-columns:var(--list-cols,1fr 160px 130px 120px 130px 28px);gap:12px;align-items:center;
  padding:0 12px;min-height:50px;border-bottom:1px solid var(--line-2);
  border-radius:var(--r-sm);cursor:pointer;transition:background var(--dur-instant),box-shadow var(--dur-instant);position:relative;
}

.task-row:hover{background:var(--surface);border-bottom-color:transparent;box-shadow:var(--shadow-sm),inset 0 1px 0 var(--edge-hi)}

.task-row:focus-visible{outline:none;box-shadow:var(--ring),inset 0 1px 0 var(--edge-hi)}

[data-theme="dark"] .task-row:hover{background:var(--surface-2)}
/* ==== components.011.css ==== */
/* Аккуратное исчезновение при удалении — без bounce/поворота, просто
   мягкое затухание и лёгкое сжатие, тот же спокойный язык, что и у
   остальных переходов в списке. */
.task-row.removing,.card.removing{opacity:0;transform:scale(.98);transition:opacity var(--dur-fast) ease,transform var(--dur-fast) ease;pointer-events:none}
/* ==== features.006.css ==== */
.task-main{display:flex;align-items:center;gap:11px;min-width:0}

.task-check{
  width:19px;height:19px;border-radius:50%;border:1.6px solid var(--line-3);flex-shrink:0;
  display:flex;align-items:center;justify-content:center;transition:var(--dur-fast);background:transparent;
}

.task-check:hover{border-color:var(--ok)}

.task-check svg{opacity:0;transform:scale(.4);transition:var(--dur-fast);color:var(--on-solid)}

.task-row.done .task-check{background:var(--ok);border-color:var(--ok)}

.task-row.done .task-check svg{opacity:1;transform:scale(1)}

.task-name{font-size:var(--t-body);font-weight:500;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;transition:color var(--dur) ease,text-decoration-color var(--dur) ease}

.task-row.done .task-name{color:var(--faint);text-decoration:line-through}
/* ==== components.012.css ==== */
.task-sub-badge{font-family:var(--mono);font-size:var(--t-micro);color:var(--faint);display:inline-flex;align-items:center;gap:3px;flex-shrink:0}
/* ==== utilities.017.css ==== */
.cell-assignee{display:flex;align-items:center;gap:7px;min-width:0}

.cell-assignee .nm{font-size:var(--t-sm);color:var(--ink-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.cell-empty{width:26px;height:26px;border-radius:50%;border:1.4px dashed var(--line-3);display:flex;align-items:center;justify-content:center;color:var(--faint);transition:var(--dur-fast)}
/* ==== components.013.css ==== */
/* Пустой приоритет на карточке доски — тот же приглушённый стиль
   пунктирной подсказки, что и .cell-empty, но в форме пилюли под текст */
.card-tag-ghost{display:inline-flex;align-items:center;gap:4px;border:1.2px dashed var(--line-3);background:transparent;color:var(--faint);cursor:pointer;font-weight:500}

.card-tag-ghost:hover{border-color:var(--accent-line);color:var(--accent-700)}

[data-theme="dark"] .card-tag-ghost:hover{color:var(--accent-600)}
/* ==== utilities.018.css ==== */
.cell-empty:hover{border-color:var(--accent);color:var(--accent)}

.due-pill{font-family:var(--mono);font-size:var(--t-xs);font-weight:500;padding:3px 8px;border-radius:var(--r-xs);color:var(--muted);letter-spacing:-.01em}

.due-pill.today{background:var(--warn-soft);color:var(--warn);font-weight:600}

.due-pill.over{background:var(--danger-soft);color:var(--danger);font-weight:600}

.due-pill.soon{color:var(--ink-2)}

/* Метки приоритета и статуса стояли рядом в каждой строке, обе
   залитые цветом и полужирные — на длинном списке это давало
   рябь, в которой ничего не выделяется, потому что выделено всё.
   Насыщенность снижена до обычной, заливка осталась: цвет по-
   прежнему различает значения, но больше не соревнуется с
   названием задачи за внимание. */
.prio-tag{display:inline-flex;align-items:center;gap:5px;font-size:var(--t-xs);font-weight:500;padding:3px 9px;border-radius:var(--r-pill)}

.prio-tag .pd{width:6px;height:6px;border-radius:50%}

.status-tag{display:inline-flex;align-items:center;font-size:var(--t-xs);font-weight:500;padding:3px 10px;border-radius:var(--r-pill)}

.add-row{display:flex;align-items:center;gap:10px;padding:8px 12px 8px 12px;color:var(--faint);font-size:var(--t-body);cursor:text;border-radius:var(--r-sm);transition:background var(--dur-instant),color var(--dur-instant);border:1px solid transparent}

.add-row:hover{color:var(--accent)}

/* :outline:none на поле уже был раньше — так и остаётся, кнопка
   создания задачи не нуждается в рамке ВНУТРИ строки. Но чтобы
   момент «сейчас пишу сюда» был вообще заметен, подсветка переходит
   на весь ряд — то же кольцо фокуса, что и у остальных полей ввода
   в приложении, просто на другом элементе. Без этого клик по полю
   ничем не отличался от простого наведения — не сразу понятно,
   активно оно или нет. */
.add-row:focus-within{background:var(--surface);border-color:var(--accent-line);color:var(--ink)}

.add-row svg{width:16px;height:16px}
/* ==== components.014.css ==== */
.add-row input{flex:1;border:none;background:transparent;font-size:var(--t-body);outline:none;color:inherit}
/* ==== utilities.019.css ==== */
.add-section-row{margin:14px 12px}
/* ==== components.015.css ==== */
.add-section-input{width:min(320px,100%);height:var(--ctl-h);padding:0 12px;border:1px solid var(--accent);border-radius:var(--r-ctl);font-size:var(--t-body);font-weight:600;background:var(--surface);outline:none;box-shadow:var(--ring)}

.add-section-btn{margin:14px 12px;display:inline-flex;align-items:center;gap:8px;color:var(--muted);font-weight:600;font-size:var(--t-body);padding:7px 12px;border-radius:var(--r-sm)}

.add-section-btn:hover{background:var(--surface-3);color:var(--ink)}
/* ==== features.007.css ==== */
/* ============================================================ BOARD VIEW */
/* Доска: колонка — утопленная ёмкость, карточка — поднятая плоскость.
   Разница уровней делает перетаскивание физически считываемым. */
.board-wrap{display:flex;gap:16px;padding:20px var(--gutter) 44px;overflow-x:auto;height:100%;align-items:flex-start}

.board-col{width:300px;flex-shrink:0;background:var(--well);border:1px solid var(--line-2);border-radius:var(--r-lg);display:flex;flex-direction:column;max-height:100%}

[data-theme="dark"] .board-col{border-color:transparent;box-shadow:inset 0 0 0 1px rgba(255,255,255,.02)}

.board-col.drag-over{border-color:var(--accent-line);background:var(--accent-soft-2)}
/* ==== utilities.020.css ==== */
/* --- Пустая колонка: раньше — просто пустое место высотой 20px,
   визуально неотличимое от «здесь ничего нет и быть не может» от
   реальной зоны сброса. Подсказка увеличивает и площадь, и
   узнаваемость цели одновременно — без новой логики, тот же
   .bc-body, что уже принимает drop. На время самого перетаскивания
   подсказка уступает место карточке (переиспользует существующий
   .drag-over на колонке, не новое состояние). */
.bc-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;
  min-height:76px;border:1.5px dashed var(--line-3);border-radius:var(--r-md);
  color:var(--faint);font-size:var(--t-xs);text-align:center;padding:10px}

.bc-empty svg{transform:rotate(90deg);opacity:.7}
/* ==== features.008.css ==== */
.board-col.drag-over .bc-empty{display:none}
/* ==== utilities.021.css ==== */
.bc-head{display:flex;align-items:center;gap:9px;padding:14px 14px 10px;flex-shrink:0}

.bc-dot{width:8px;height:8px;border-radius:3px;flex-shrink:0}

.bc-title{font-weight:700;font-size:var(--t-body);letter-spacing:-.01em;color:var(--ink);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.bc-count{font-family:var(--mono);font-size:var(--t-xs);color:var(--muted);background:var(--surface-3);padding:1px 7px;border-radius:var(--r-pill);font-weight:500}
/* ==== components.016.css ==== */
.bc-head .bc-menu{margin-left:auto;width:24px;height:24px;border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;color:var(--faint);transition:var(--dur-instant)}

.bc-head .bc-menu:hover{background:var(--surface-3);color:var(--ink)}
/* ==== utilities.022.css ==== */
.bc-body{flex:1;overflow-y:auto;padding:2px 10px 10px;display:flex;flex-direction:column;gap:8px;min-height:20px}

.bc-body::-webkit-scrollbar{width:8px}
/* ==== components.017.css ==== */
.card{
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-md);
  padding:12px 13px;box-shadow:var(--shadow-sm),inset 0 1px 0 var(--edge-hi);
  cursor:pointer;transition:box-shadow var(--dur-fast),border-color var(--dur-fast),transform var(--dur-fast);
  content-visibility:auto;contain-intrinsic-size:0 92px;
}

.card:hover{border-color:var(--line-3);box-shadow:var(--shadow),inset 0 1px 0 var(--edge-hi);transform:translateY(-1px)}

.card:focus-visible{outline:none;border-color:var(--accent);box-shadow:var(--ring)}

.card.dragging{opacity:.45;transform:rotate(1.5deg) scale(.99);box-shadow:var(--shadow-lg)}

.card-top{display:flex;align-items:center;gap:8px;margin-bottom:8px}

.card-more{width:22px;height:22px;flex-shrink:0;display:flex;align-items:center;justify-content:center;
  border-radius:var(--r-xs);color:var(--faint);opacity:0;transition:opacity var(--dur-instant),background var(--dur-instant)}

.card:hover .card-more,.card-more:focus-visible{opacity:1}

.card-more:hover{background:var(--surface-3);color:var(--ink-2)}

.card-more:focus-visible{outline:none;box-shadow:var(--ring)}

.card-check{width:17px;height:17px;border-radius:50%;border:1.5px solid var(--line-3);flex-shrink:0;display:flex;align-items:center;justify-content:center;transition:var(--dur-fast)}

.card-check svg{opacity:0;color:var(--on-solid)}

.card.done .card-check{background:var(--ok);border-color:var(--ok)}

.card.done .card-check svg{opacity:1}

.card-title{font-size:var(--t-body);font-weight:500;line-height:1.4;color:var(--ink);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;transition:color var(--dur) ease}

.card.done .card-title{color:var(--faint);text-decoration:line-through}

.card-meta{display:flex;align-items:center;gap:8px;margin-top:9px;flex-wrap:wrap}

.card-tag{display:inline-flex;align-items:center;gap:4px;font-size:var(--t-micro);font-weight:600;padding:2px 7px;border-radius:var(--r-xs);letter-spacing:.01em}

.card-foot{display:flex;align-items:center;gap:8px;margin-top:9px}

.card-foot .spacer{flex:1}
/* ==== utilities.023.css ==== */
.bc-add{display:flex;align-items:center;gap:8px;padding:9px 12px;margin:0 10px 10px;color:var(--muted);font-weight:500;font-size:var(--t-body);border-radius:var(--r-sm);cursor:pointer;transition:var(--dur-instant)}

.bc-add:hover{background:var(--surface);color:var(--ink);box-shadow:var(--shadow-xs)}

[data-theme="dark"] .bc-add:hover{background:var(--surface-2)}
/* ==== features.009.css ==== */
.board-addcol{width:280px;flex-shrink:0}
/* ==== components.018.css ==== */
.board-addcol button{width:100%;display:flex;align-items:center;justify-content:center;gap:8px;padding:14px;border:1.5px dashed var(--line-3);border-radius:var(--r-lg);color:var(--muted);font-weight:600;font-size:var(--t-body);background:transparent;transition:var(--dur-fast)}

.board-addcol button:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-soft-2)}
/* ==== utilities.024.css ==== */
/* ============================================================ CALENDAR */
.cal-wrap{padding:20px var(--gutter) 44px}

.cal-head{display:flex;align-items:center;gap:14px;margin-bottom:16px}

.cal-title{font-size:var(--t-h2);font-weight:700;letter-spacing:-.025em;min-width:190px;color:var(--ink)}
/* ==== layout.006.css ==== */
.cal-nav{display:flex;gap:4px}

.cal-nav button{width:32px;height:32px;border-radius:var(--r-sm);border:1px solid var(--line);background:var(--surface);box-shadow:var(--shadow-xs);display:flex;align-items:center;justify-content:center;color:var(--muted);transition:var(--dur-fast)}

.cal-nav button:hover{background:var(--surface-3);color:var(--ink)}

[data-theme="dark"] .cal-nav button{background:var(--surface-2)}

.cal-grid{display:grid;grid-template-columns:repeat(7,1fr);border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;background:var(--surface);box-shadow:var(--shadow-sm)}
/* ==== utilities.025.css ==== */
.cal-dow{padding:10px 12px;font-size:var(--t-xs);font-weight:600;color:var(--faint);border-right:1px solid var(--line-2);border-bottom:1px solid var(--line);background:var(--surface-2)}

.cal-cell{min-height:108px;border-right:1px solid var(--line-2);border-bottom:1px solid var(--line-2);padding:7px 8px;position:relative;transition:background var(--dur-instant)}

.cal-cell:hover{background:var(--surface-2)}

.cal-cell.other{background:var(--well);opacity:.55}

.cal-daynum{font-family:var(--mono);font-size:var(--t-xs);font-weight:500;color:var(--muted);width:24px;height:24px;display:flex;align-items:center;justify-content:center;border-radius:var(--r-xs);margin-bottom:4px}

.cal-cell.today{background:var(--accent-soft-2)}

.cal-cell.today .cal-daynum{background:var(--accent);color:var(--accent-fg);font-weight:600;box-shadow:var(--shadow-sm)}

.cal-ev{display:flex;align-items:center;gap:6px;padding:3px 7px;border-radius:var(--r-xs);font-size:var(--t-xs);font-weight:500;margin-bottom:3px;cursor:pointer;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}

.cal-ev .ed{width:6px;height:6px;border-radius:2px;flex-shrink:0}

.cal-ev:hover{filter:brightness(.96)}

.cal-ev:focus-visible{outline:none;box-shadow:var(--ring)}

.cal-more{font-size:var(--t-xs);color:var(--faint);font-weight:600;padding:1px 7px}

/* ============================================================ TIMELINE */

/* ============================================================ DASHBOARD / CHARTS */
/* --- Панель фильтров аналитики -------------------------------
   Стоит над блоками и использует те же чипы, что панель задач, —
   один визуальный язык для «сузить показанное» во всём продукте. */
.dash-filters{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  padding:0 var(--gutter) 4px}

.dash-f{appearance:none;-webkit-appearance:none;cursor:pointer;
  padding-right:26px;background-image:none;max-width:200px}

.dash-f-note{margin-left:auto;font-size:var(--t-sm);color:var(--faint);white-space:nowrap}

@media(max-width:768px){
  /* Фильтры прокручиваются вбок: четыре списка в столбик заняли бы
     пол-экрана раньше, чем показались сами цифры. */
  .dash-filters{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;padding-left:12px;padding-right:12px}
  .dash-filters::-webkit-scrollbar{display:none}
  .dash-f{flex:0 0 auto;min-height:40px}
  .dash-f-note{display:none}
}

.dash-wrap{padding:24px var(--gutter) 56px;display:grid;grid-template-columns:repeat(12,1fr);gap:18px}
/* ==== components.019.css ==== */
.stat-card{grid-column:span 3;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);padding:18px 20px;box-shadow:var(--shadow-sm),inset 0 1px 0 var(--edge-hi)}
/* ==== utilities.026.css ==== */
.stat-label{font-size:var(--t-xs);font-weight:600;color:var(--muted);display:flex;align-items:center;gap:8px;letter-spacing:.01em}

.stat-icon{width:28px;height:28px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;box-shadow:inset 0 0 0 1px rgba(0,0,0,.04)}

.stat-value{font-size:32px;font-weight:700;letter-spacing:-.04em;margin-top:12px;font-variant-numeric:tabular-nums;line-height:1.05;color:var(--ink)}

.stat-sub{font-size:var(--t-xs);color:var(--faint);margin-top:5px;font-family:var(--mono);letter-spacing:-.01em}
/* ==== components.020.css ==== */
.chart-card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);padding:20px 22px;box-shadow:var(--shadow-sm),inset 0 1px 0 var(--edge-hi)}

.chart-card.half{grid-column:span 6}

.chart-card.third{grid-column:span 4}

.chart-card.full{grid-column:span 12}
/* ==== utilities.027.css ==== */
.chart-title{font-size:var(--t-h3);font-weight:700;margin-bottom:3px;letter-spacing:-.02em;color:var(--ink)}

.chart-desc{font-size:var(--t-sm);color:var(--faint);margin-bottom:18px;line-height:1.45}

/* ============================================================
   СТРОКИ ВИДЖЕТОВ DASHBOARD — У НИХ НЕ БЫЛО СВОЕГО CSS ВООБЩЕ
   .dash-list-row, .dash-list-tx, .dash-list-proj и вся группа
   .dash-proj-* использовались в разметке (Просрочено, Сегодня,
   Ближайшие дедлайны, Без исполнителя, Активные/Завершённые
   проекты), но ни одного правила для них не было — только то, что
   давали браузерные значения по умолчанию для div/span. Отсюда и
   ощущение «слепленности»: аватар, название задачи, эмодзи проекта
   и дата просто шли инлайн-потоком без выравнивания, а строки не
   отделялись друг от друга ничем. */
.dash-list{display:flex;flex-direction:column}

.dash-list-row{display:flex;align-items:center;gap:10px;padding:9px 4px;border-radius:var(--r-sm);cursor:pointer;transition:background var(--dur-instant);border-bottom:1px solid var(--line-2)}

.dash-list-row:last-child{border-bottom:none}

.dash-list-row:hover{background:var(--surface-2)}

.dash-list-tx{flex:1;min-width:0;font-size:var(--t-body);font-weight:500;color:var(--ink-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.dash-list-proj{font-size:var(--t-h2);flex-shrink:0}

.dash-proj-row{display:flex;align-items:center;gap:10px;padding:9px 4px;border-radius:var(--r-sm);cursor:pointer;transition:background var(--dur-instant);border-bottom:1px solid var(--line-2)}

.dash-proj-row:last-child{border-bottom:none}

.dash-proj-row:hover{background:var(--surface-2)}

.dash-proj-emoji{font-size:var(--t-lg);flex-shrink:0}

.dash-proj-name{flex:1;min-width:0;font-size:var(--t-body);font-weight:500;color:var(--ink-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.dash-proj-bar{width:88px;height:6px;border-radius:var(--r-pill);background:var(--well);overflow:hidden;flex-shrink:0}

.dash-proj-bar div{height:100%;border-radius:var(--r-pill);transition:width .5s ease}

.dash-proj-pct{font-family:var(--mono);font-size:var(--t-xs);color:var(--faint);width:32px;text-align:right;flex-shrink:0}

.dash-proj-done{display:flex;align-items:center;gap:5px;font-size:var(--t-xs);color:var(--ok);font-weight:600;flex-shrink:0}

.donut-legend{display:flex;flex-direction:column;gap:9px}

.dl-item{display:flex;align-items:center;gap:9px;font-size:var(--t-body)}

.dl-dot{width:10px;height:10px;border-radius:3px}

.dl-name{color:var(--ink-2)}

.dl-val{margin-left:auto;font-family:var(--mono);font-weight:600;font-size:var(--t-body)}

.bar-row{display:flex;align-items:center;gap:12px;margin-bottom:13px}

.bar-name{width:130px;font-size:var(--t-sm);font-weight:500;display:flex;align-items:center;gap:8px;flex-shrink:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.bar-track{flex:1;height:26px;background:var(--well);border-radius:var(--r-sm);overflow:hidden;position:relative;box-shadow:inset 0 0 0 1px var(--line-2)}

.bar-fill{height:100%;border-radius:var(--r-sm);display:flex;align-items:center;padding-left:10px;font-family:var(--mono);font-size:var(--t-xs);font-weight:600;color:var(--on-solid);min-width:24px;transition:width .5s cubic-bezier(.4,0,.2,1);box-shadow:inset 0 1px 0 rgba(255,255,255,.2)}

/* ============================================================ HOME */
.home-wrap{max-width:1120px;margin:0 auto;padding:32px var(--gutter) 64px}

/* Отступ снизу уменьшен: ряд быстрых действий поднимается ближе
   к приветствию и, соответственно, дальше от вкладок под ним —
   раньше он висел ровно посередине и не читался как часть шапки. */
.home-hero{text-align:left;padding:14px 0 16px}

.home-date{font-size:var(--t-xs);color:var(--faint);font-weight:500}

/* Раньше здесь стояли 34px по центру экрана — крупнее самого
   большого именованного размера во всей типографике (--t-display,
   28px), да ещё и по центру, что превращало приветствие в
   декоративный «баннер», который зрительно спорит с действительно
   важным контентом ниже (задачи, входящие, проекты), а не уступает
   ему главную роль. Теперь — самый крупный размер из существующей
   шкалы, без изобретения нового, и по левому краю, как у остального
   текста экрана: приветствие остаётся приветствием, а не витриной. */
.home-greet{font-size:var(--t-display);font-weight:700;letter-spacing:-.03em;margin-top:6px;line-height:1.15;color:var(--ink)}

.home-kpis{display:flex;justify-content:center;gap:8px;margin-top:14px;flex-wrap:wrap}

/* --- Быстрые действия главного экрана -------------------------
   Пять кнопок в ряд, переносятся при нехватке ширины. Главная
   («Создать задачу») окрашена — она одна на экране должна быть
   очевидна с первого взгляда, остальные нейтральны. */
.home-qa{display:inline-flex;align-items:center;gap:7px;height:var(--ctl-h);padding:0 14px;
  border:1px solid var(--line);border-radius:var(--r-pill);background:var(--surface);
  color:var(--ink-2);font-size:var(--t-sm);font-weight:600;white-space:nowrap;
  box-shadow:var(--shadow-xs);transition:var(--dur-fast);cursor:pointer}

.home-qa:hover{background:var(--surface-3);color:var(--ink);border-color:var(--line-3)}

/* 2.288.0: текст — var(--accent-fg), как у всех главных кнопок (.btn-primary):
   в тёмной теме акцент светлый (#8B7DF5), и белый текст давал 3,3:1
   (WCAG AA — 4,5:1); --accent-fg там тёмный. */
.home-qa.primary{background:var(--accent);border-color:var(--accent);color:var(--accent-fg)}

.home-qa.primary:hover{background:var(--accent-700);border-color:var(--accent-700)}

.home-qa-n{background:var(--danger-soft);color:var(--danger);border-radius:var(--r-pill);
  padding:1px 7px;font-size:var(--t-micro);font-weight:700}
/* ==== features.010.css ==== */
/* ============================================================
   HOME: КОМПАКТНЫЕ ГРУППЫ ЗАДАЧ ВНУТРИ ВИДЖЕТА «МОИ ЗАДАЧИ»
   Три подряд идущие корзины (просрочено/сегодня/ближайшие сроки)
   внутри одного widget — с маленьким заголовком-леблом, а не
   отдельными карточками: это по-прежнему один список задач, а не
   три самостоятельных блока статистики. */
.home-tasksec{margin-top:4px}

.home-tasksec:first-child{margin-top:0}

.home-tasksec-h{display:flex;align-items:center;gap:7px;font-size:var(--t-xs);font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:var(--faint);padding:10px 0 4px}

.home-tasksec-h svg{width:13px;height:13px}

.home-tasksec-h .cnt{font-family:var(--mono);font-weight:500;color:var(--faint)}

.home-tasksec-more{font-size:var(--t-sm);color:var(--accent);cursor:pointer;padding:6px 8px;font-weight:600}

.home-tasksec-more:hover{text-decoration:underline}
/* ==== utilities.028.css ==== */
.home-inbox-item{border-bottom:1px solid var(--line-2);border-radius:0;padding:10px 4px}

.home-inbox-item:last-child{border-bottom:none}

.home-proj-row{padding:9px 4px}

.home-wrap.home-wrap-simple{max-width:720px}

.home-kpis-simple{justify-content:flex-start}

/* --- Статистика: четыре компактных числа сразу под приветствием ---
   Не .stat-card из dash-wrap (та сетка на 12 колонок рассчитана под
   другой, более плотный экран отчётов) — здесь узкая колонка (720px),
   свой лёгкий вариант в один ряд, тот же язык карточки (surface +
   line + shadow-xs), что и остальной Home, просто мельче. Клик по
   ячейке — не декорация: три из четырёх ведут туда, где эта цифра
   разбирается на отдельные задачи. */
.home-stats{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin-top:16px}

.home-stat{display:flex;align-items:center;gap:10px;padding:12px 12px;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--shadow-xs);min-width:0}

.home-stat-link{cursor:pointer;transition:var(--dur-fast)}

.home-stat-link:hover{background:var(--surface-2);border-color:var(--line-3);transform:translateY(-1px);box-shadow:var(--shadow-sm)}

.home-stat-ic{width:30px;height:30px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;flex-shrink:0}

.home-stat-n{font-size:var(--t-h2);font-weight:700;letter-spacing:-.02em;line-height:1.1;font-variant-numeric:tabular-nums}

.home-stat-l{font-size:var(--t-xs);color:var(--muted);margin-top:1px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* Полоска прогресса под названием проекта в «Последних проектах» —
   тонкая линия, а не крупное кольцо (см. комментарий у recentProjRows
   в viewHome): та же цифра, что уже показана числом рядом (…%), но
   считываемая и без чтения текста, одним взглядом по ряду. */
.home-proj-bar{height:3px;border-radius:2px;background:var(--line-2);margin-top:6px;overflow:hidden}

.home-proj-bar-fill{height:100%;border-radius:2px}
/* ==== components.021.css ==== */
/* Счётчик на вкладке: просрочка выделена цветом, остальные нейтральны —
   иначе выделено всё и не выделено ничего. */
.home-tab-n{display:inline-block;margin-left:6px;padding:1px 6px;border-radius:var(--r-pill);
  background:var(--surface-3);color:var(--muted);font-size:var(--t-micro);font-weight:700}

.home-tab-n.hot{background:var(--danger-soft);color:var(--danger)}

.home-tab.active .home-tab-n{background:var(--accent-soft);color:var(--accent-700)}

.home-tab.active .home-tab-n.hot{background:var(--danger-soft);color:var(--danger)}
/* ==== utilities.029.css ==== */
/* Причина попадания в «Требуют внимания» */
.mini-why{font-size:var(--t-micro);color:var(--warn);font-weight:600;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;max-width:100%}

@media(max-width:768px){
  /* На телефоне ряд действий прокручивается вбок, а не переносится
     в три этажа, съедая экран до того, как человек увидит задачи. */
  .home-kpis{flex-wrap:nowrap;overflow-x:auto;justify-content:flex-start;
    scrollbar-width:none;padding-bottom:2px;margin-top:10px}
  .home-kpis::-webkit-scrollbar{display:none}
  .home-qa{flex:0 0 auto;min-height:44px}
  .home-tabs{overflow-x:auto;scrollbar-width:none;gap:14px}
  .home-tabs::-webkit-scrollbar{display:none}
  .home-tab{flex:0 0 auto}
}

.home-kpi{display:flex;align-items:center;gap:10px;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-xl);padding:8px 16px 8px 10px;box-shadow:var(--shadow-sm),inset 0 1px 0 var(--edge-hi)}

.hk-icon{width:28px;height:28px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;box-shadow:inset 0 0 0 1px rgba(0,0,0,.04)}

.hk-num{font-weight:700;font-size:var(--t-lg);font-variant-numeric:tabular-nums;letter-spacing:-.03em;color:var(--ink)}

.hk-lbl{font-size:var(--t-sm);color:var(--muted);font-weight:500}
/* ==== layout.007.css ==== */
.home-grid{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:26px}
/* ==== utilities.030.css ==== */
.widget{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);padding:20px 22px;box-shadow:var(--shadow-sm),inset 0 1px 0 var(--edge-hi)}

.widget.wide{grid-column:1/-1}

.widget-head{display:flex;align-items:center;gap:12px;margin-bottom:16px}
/* ==== components.022.css ==== */
.widget-head .avatar,.widget-head .w-emoji{flex-shrink:0}
/* ==== utilities.031.css ==== */
.w-emoji{width:34px;height:34px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;font-size:var(--t-h2);box-shadow:inset 0 0 0 1px rgba(0,0,0,.05)}

.widget-title{font-weight:700;font-size:var(--t-h3);letter-spacing:-.02em;color:var(--ink)}

.widget-sub{font-size:var(--t-sm);color:var(--faint);margin-top:1px}

.widget-head .w-action{margin-left:auto}
/* ==== components.023.css ==== */
.home-tabs{display:flex;gap:18px;border-bottom:1px solid var(--line);margin-bottom:8px}

.home-tab{font-size:var(--t-sm);font-weight:600;color:var(--muted);padding:0 0 10px;border-bottom:2px solid transparent;margin-bottom:-1px;cursor:pointer;transition:color var(--dur-instant)}

.home-tab:hover{color:var(--ink)}

.home-tab.active{color:var(--accent-700);border-bottom-color:var(--accent)}

[data-theme="dark"] .home-tab.active{color:var(--accent-600)}
/* ==== features.011.css ==== */
.mini-task{display:flex;align-items:center;gap:11px;padding:10px 8px;margin:0 -8px;border-radius:var(--r-sm);border-bottom:1px solid var(--line-2);cursor:pointer;transition:background var(--dur-instant)}

.mini-task:hover{background:var(--surface-2);border-bottom-color:transparent}

.mini-task:last-child{border-bottom:none}
/* ==== utilities.032.css ==== */
.mini-check{width:18px;height:18px;border-radius:50%;border:1.5px solid var(--line-3);flex-shrink:0;display:flex;align-items:center;justify-content:center;transition:var(--dur-fast)}

.mini-check svg{opacity:0;color:var(--on-solid)}
/* ==== features.012.css ==== */
.mini-task.done .mini-check{background:var(--ok);border-color:var(--ok)}

.mini-task.done .mini-check svg{opacity:1}
/* ==== utilities.033.css ==== */
.mini-name{font-size:var(--t-body);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* ==== features.013.css ==== */
.mini-task.done .mini-name{color:var(--faint);text-decoration:line-through}
/* ==== utilities.034.css ==== */
.mini-proj{font-size:var(--t-micro);font-weight:600;padding:2px 8px;border-radius:var(--r-xs);flex-shrink:0}

.proj-tile{display:flex;align-items:center;gap:13px;padding:11px 8px;margin:0 -8px;border-radius:var(--r-sm);border-bottom:1px solid var(--line-2);cursor:pointer;transition:background var(--dur-instant)}

.proj-tile:last-child{border:none}

.proj-tile:hover{background:var(--surface-2);border-bottom-color:transparent}

.proj-emoji{width:38px;height:38px;border-radius:var(--r-md);display:flex;align-items:center;justify-content:center;font-size:var(--t-lg);flex-shrink:0;box-shadow:inset 0 0 0 1px rgba(0,0,0,.05)}

.proj-tile .pn{font-weight:600;font-size:var(--t-body);color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.proj-tile .pm{font-size:var(--t-xs);color:var(--faint);font-family:var(--mono);letter-spacing:-.01em;margin-top:1px}

.proj-prog{margin-left:auto;flex-shrink:0}
/* ==== layout.008.css ==== */
.people-grid{display:grid;grid-template-columns:1fr 1fr;gap:4px}
/* ==== utilities.035.css ==== */
.person-tile{display:flex;align-items:center;gap:11px;padding:9px 8px;border-radius:var(--r-sm);cursor:pointer;transition:background var(--dur-instant)}

.person-tile:hover{background:var(--surface-2)}

.person-tile .pn{font-weight:600;font-size:var(--t-body)}

.person-tile .pr{font-size:var(--t-xs);color:var(--faint)}

/* ============================================================ GOALS */
.goals-wrap{max-width:960px;margin:0 auto;padding:28px var(--gutter) 64px}
/* ==== components.024.css ==== */
.goal-card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);padding:20px 22px;margin-bottom:14px;box-shadow:var(--shadow-sm),inset 0 1px 0 var(--edge-hi);display:flex;align-items:center;gap:22px;transition:box-shadow var(--dur-fast),border-color var(--dur-fast)}

.goal-card:hover{box-shadow:var(--shadow),inset 0 1px 0 var(--edge-hi);border-color:var(--line-3)}
/* ==== utilities.036.css ==== */
.goal-main{flex:1;min-width:0}

.goal-q{font-family:var(--mono);font-size:var(--t-xs);font-weight:600;color:var(--accent-700)}

[data-theme="dark"] .goal-q{color:var(--accent-600)}

.goal-title{font-size:var(--t-h2);font-weight:700;margin:6px 0 8px;letter-spacing:-.025em;color:var(--ink)}

.goal-owner{display:flex;align-items:center;gap:8px;font-size:var(--t-sm);color:var(--muted)}
/* ==== features.014.css ==== */
.goal-projects{display:flex;gap:6px;margin-top:10px;flex-wrap:wrap}
/* ==== utilities.037.css ==== */
.gp-chip{font-size:var(--t-xs);font-weight:600;padding:3px 9px;border-radius:var(--r-xs);display:inline-flex;align-items:center;gap:5px}

.ring-wrap{position:relative;width:74px;height:74px;flex-shrink:0}

.ring-label{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;pointer-events:none}

.ring-pct{font-weight:700;font-size:var(--t-lg);font-variant-numeric:tabular-nums;letter-spacing:-.03em;color:var(--ink)}

.ring-cap{font-size:var(--t-micro);color:var(--faint);font-weight:500}

/* ============================================================ PORTFOLIO */
.pf-wrap{padding:24px var(--gutter) 64px}
/* ==== components.025.css ==== */
.pf-table{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;box-shadow:var(--shadow-sm),inset 0 1px 0 var(--edge-hi)}
/* ==== utilities.038.css ==== */
.pf-thead{display:grid;grid-template-columns:1.6fr 1fr 1fr 130px 120px 32px;gap:14px;padding:12px 20px;border-bottom:1px solid var(--line);background:var(--surface-2);font-size:var(--t-xs);font-weight:600;color:var(--faint);}

.pf-row{display:grid;grid-template-columns:1.6fr 1fr 1fr 130px 120px 32px;gap:14px;padding:15px 20px;border-bottom:1px solid var(--line-2);align-items:center;cursor:pointer;transition:background var(--dur-instant)}

.pf-row:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--accent)}

.pf-row-remove{opacity:0;width:26px;height:26px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;color:var(--faint);transition:var(--dur-instant);justify-self:end}

.pf-row:hover .pf-row-remove,.pf-row-remove:focus-visible{opacity:1}

.pf-row-remove:hover{background:var(--danger-soft);color:var(--danger)}

.pf-row-remove:focus-visible{outline:none;box-shadow:var(--ring)}
/* ==== components.026.css ==== */
.ph-star-btn{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;border-radius:var(--r-sm);color:var(--faint);margin-right:2px;transition:var(--dur-instant);vertical-align:middle}

.ph-star-btn:hover{background:var(--surface-2);color:var(--warn)}

.ph-star-btn.on{color:var(--warn)}

.ph-star-btn.on svg{fill:currentColor}
/* ==== utilities.039.css ==== */
.pf-row:last-child{border:none}

.pf-row:hover{background:var(--surface-2)}

.pf-name{display:flex;align-items:center;gap:11px;font-weight:600;font-size:var(--t-body);min-width:0;color:var(--ink)}

.pf-status{display:inline-flex;align-items:center;gap:6px;font-size:var(--t-sm);font-weight:600;padding:3px 10px;border-radius:var(--r-pill);width:fit-content}

.pf-prog-cell{display:flex;align-items:center;gap:10px}

.pf-prog-track{flex:1;height:6px;background:var(--well);border-radius:var(--r-pill);overflow:hidden;box-shadow:inset 0 0 0 1px var(--line-2)}

.pf-prog-fill{height:100%;border-radius:var(--r-pill)}

.pf-prog-num{font-family:var(--mono);font-size:var(--t-sm);font-weight:600;width:34px;text-align:right}

/* ============================================================ INBOX */
.inbox-wrap{max-width:800px;margin:0 auto;padding:22px var(--gutter) 64px}
/* ==== components.027.css ==== */
/* --- Вкладки категорий уведомлений ---------------------------
   Тот же облик, что у вкладок главного экрана: одинаковый элемент
   должен выглядеть одинаково, иначе человек изучает его заново. */
.inbox-tabs{display:flex;align-items:center;gap:14px;padding:0 4px 10px;
  border-bottom:1px solid var(--line-2);margin-bottom:4px;overflow-x:auto;scrollbar-width:none}

.inbox-tabs::-webkit-scrollbar{display:none}

.inbox-tab{flex:0 0 auto;font-size:var(--t-sm);font-weight:600;color:var(--muted);
  padding:4px 0;border-bottom:2px solid transparent;margin-bottom:-11px;cursor:pointer;
  display:inline-flex;align-items:center;gap:6px;white-space:nowrap}

.inbox-tab:hover{color:var(--ink-2)}

.inbox-tab.active{color:var(--accent-700);border-bottom-color:var(--accent)}

.inbox-tab-n{background:var(--accent-soft);color:var(--accent-700);border-radius:var(--r-pill);
  padding:1px 6px;font-size:var(--t-micro);font-weight:700}

.inbox-tab:not(.active) .inbox-tab-n{background:var(--surface-3);color:var(--muted)}
/* ==== utilities.040.css ==== */
/* Кнопка «прочитано» — незаметна в покое, чтобы лента оставалась
   спокойной, но всегда доступна на сенсорных экранах. */
.inbox-item{position:relative}

.inbox-read{position:absolute;right:12px;top:50%;transform:translateY(-50%);
  width:28px;height:28px;display:flex;align-items:center;justify-content:center;
  border-radius:var(--r-xs);color:var(--faint);opacity:0;transition:opacity var(--dur-instant),background var(--dur-instant)}

.inbox-item:hover .inbox-read{opacity:1}

.inbox-read:hover{background:var(--ok-soft);color:var(--ok)}

@media(hover:none){.inbox-read{opacity:1}}

.inbox-day{font-size:var(--t-xs);font-weight:600;color:var(--faint);padding:20px 4px 10px}

.inbox-item{display:flex;gap:13px;padding:14px 16px;border-radius:var(--r-md);cursor:pointer;transition:background var(--dur-instant),box-shadow var(--dur-instant);position:relative;border:1px solid transparent}

.inbox-item:hover{background:var(--surface);border-color:var(--line);box-shadow:var(--shadow-xs)}

[data-theme="dark"] .inbox-item:hover{background:var(--surface-2)}

.inbox-item.unread{background:var(--surface);border-color:var(--line);box-shadow:var(--shadow-sm),inset 0 1px 0 var(--edge-hi)}

[data-theme="dark"] .inbox-item.unread{background:var(--surface-2)}

.inbox-item.unread::before{content:"";position:absolute;left:5px;top:50%;transform:translateY(-50%);width:5px;height:5px;border-radius:50%;background:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}

.inbox-ic{width:34px;height:34px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;flex-shrink:0;box-shadow:inset 0 0 0 1px rgba(0,0,0,.04)}

.inbox-body{flex:1;min-width:0}

.inbox-txt{font-size:var(--t-body);line-height:1.45}

.inbox-txt b{font-weight:600}

.inbox-time{font-size:var(--t-xs);color:var(--faint);font-family:var(--mono);margin-top:3px}

/* ============================================================ TASK PANEL */
/* Панель задачи — верхний уровень. Затемнение с размытием отделяет её
   от рабочей области, шапка липкая и на «стекле». */
.overlay{position:fixed;inset:0;background:rgba(15,16,32,.36);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);z-index:60;opacity:0;pointer-events:none;transition:opacity var(--dur)}

.overlay.show{opacity:1;pointer-events:auto}

[data-theme="dark"] .overlay{background:rgba(0,0,0,.58)}
/* ==== layout.009.css ==== */
/* .nav-scrim (мобильная подложка бокового меню) — тот же класс
   несогласованности, что и у остальных подложек рядом: в светлой
   теме и без того тёмный полупрозрачный чёрный фон (в отличие от
   .overlay/.modal-back, которые в светлой теме специально уходят в
   тёмно-синий, не чёрный) на глаз почти незаметно отличается по теме,
   но на тёмном фоне 40% чёрного дают заметно меньше зрительного
   отделения меню от остального интерфейса, чем нужно бы — тот же
   самый эффект, ради которого .overlay в тёмной теме поднимается
   до 58%. Подложка мобильного меню встречается едва ли не чаще
   любой другой в этом списке (каждое открытие бокового меню на
   телефоне), поэтому и выигрыш от исправления заметнее на практике,
   чем у остальных. */
[data-theme="dark"] .nav-scrim{background:rgba(0,0,0,.58)}

#panel{
  position:fixed;top:0;right:0;height:100vh;width:min(820px,94vw);
  background:var(--surface);box-shadow:var(--shadow-panel);z-index:70;
  transform:translateX(100%);transition:transform var(--dur-slow) cubic-bezier(.32,.72,0,1);
  display:flex;flex-direction:column;
}

#panel.show{transform:translateX(0)}

.panel-top{display:flex;align-items:center;gap:10px;padding:12px 18px;border-bottom:1px solid var(--line);flex-shrink:0;background:var(--glass);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}

.panel-complete{display:inline-flex;align-items:center;gap:8px;padding:7px 13px;border-radius:var(--r-sm);border:1px solid var(--line);background:var(--surface);box-shadow:var(--shadow-xs);font-weight:600;font-size:var(--t-body);color:var(--ink-2);transition:var(--dur-fast)}

.panel-complete:hover{background:var(--surface-3);border-color:var(--line-3);color:var(--ink)}

.panel-complete.done{background:var(--ok-soft);border-color:var(--ok-line);color:var(--ok);box-shadow:none}

.panel-complete svg{width:16px;height:16px}

.panel-top .spacer{flex:1}

.panel-close{width:32px;height:32px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;color:var(--muted);transition:var(--dur-instant)}

.panel-close:hover{background:var(--surface-3);color:var(--ink)}

.panel-body{flex:1;overflow-y:auto;padding:26px 28px 48px}

.panel-name{width:100%;font-size:25px;font-weight:700;letter-spacing:-.033em;border:none;background:transparent;outline:none;resize:none;line-height:1.25;margin-bottom:24px;overflow:hidden;color:var(--ink)}

.panel-name::placeholder{color:var(--faint)}

.field-grid{display:grid;grid-template-columns:126px 1fr;gap:2px 14px;align-items:center;margin-bottom:6px}
/* ==== components.028.css ==== */
.field-lbl{font-size:var(--t-sm);font-weight:500;color:var(--muted);display:flex;align-items:center;gap:9px;padding:9px 0}

.field-lbl svg{width:15px;height:15px;color:var(--faint)}

.field-val{padding:5px 0}

.field-btn{display:inline-flex;align-items:center;gap:8px;padding:6px 10px;margin-left:-10px;border-radius:var(--r-sm);font-size:var(--t-body);font-weight:500;transition:var(--dur-instant);border:1px solid transparent}

.field-btn:hover{background:var(--surface-2);border-color:var(--line-2)}

.field-btn.empty{color:var(--faint)}

.field-input{width:100%;padding:8px 11px;border:1px solid var(--line);border-radius:var(--r-sm);font-size:var(--t-body);background:var(--surface-2);transition:var(--dur-fast)}

.field-input:focus{outline:none;border-color:var(--accent);background:var(--surface);box-shadow:var(--ring)}
/* ==== layout.010.css ==== */
/* ============================================================
   ДВЕ ЗОНЫ ПАНЕЛИ ЗАДАЧИ (по образцу Asana)
   Широкая колонка слева — название/описание/подзадачи/зависимости,
   то есть содержание задачи; узкая справа — её свойства, заведомо
   мельче и компактнее, чтобы не спорить за внимание с содержанием.
   На узких панелях (телефон, панель на весь экран) колонки
   складываются в одну — тот же приём, что уже был у field-grid. */
.panel-layout{display:grid;grid-template-columns:1fr 226px;gap:0 30px;align-items:start}

.panel-main{min-width:0}

.panel-side{min-width:0;padding-top:2px}

.field-grid-side{grid-template-columns:1fr;gap:0;margin-bottom:0}

.field-grid-side .field-lbl{font-size:var(--t-xs);font-weight:600;text-transform:uppercase;letter-spacing:.03em;color:var(--faint);padding:12px 0 3px;gap:6px}

.field-grid-side .field-lbl svg{width:12px;height:12px}

.field-grid-side .field-val{padding:0 0 2px}

.field-grid-side .field-btn{font-size:var(--t-sm);padding:5px 8px;margin-left:-8px}

.panel-side-more-title{font-size:var(--t-micro);font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--faint);margin:22px 0 2px;padding-top:14px;border-top:1px solid var(--line)}

.field-grid-more .field-lbl{color:var(--faint)}
/* ==== utilities.041.css ==== */
@media(max-width:768px){
  .panel-layout{display:block}
  .panel-side{margin-top:8px;padding-top:0}
  .panel-side-more-title{margin-top:18px}
}
/* ==== layout.011.css ==== */
.panel-divider{height:1px;background:var(--line);margin:26px 0}

.panel-sec-title{font-size:var(--t-xs);font-weight:600;color:var(--faint);margin-bottom:14px;display:flex;align-items:center;gap:8px}

.panel-sec-title svg{color:var(--faint)}

.panel-sec-title .cnt{font-family:var(--mono);font-size:var(--t-xs);color:var(--faint);font-weight:500;letter-spacing:0}
/* ==== utilities.042.css ==== */
.desc-area{width:100%;min-height:72px;border:1px solid var(--line);border-radius:var(--r-md);padding:12px 14px;font-size:var(--t-body);line-height:1.6;background:var(--surface-2);resize:vertical;transition:var(--dur-fast)}

.desc-area:focus{outline:none;border-color:var(--accent);background:var(--surface);box-shadow:var(--ring)}

.desc-area::placeholder{color:var(--faint)}

.desc-rendered{font-size:var(--t-body);line-height:1.65;color:var(--ink-2);cursor:text;border:1px solid transparent;border-radius:var(--r-md);padding:10px 12px;margin-left:-12px;transition:var(--dur-instant)}

.desc-rendered:hover{border-color:var(--line);background:var(--surface-2)}

.desc-empty{font-size:var(--t-body);color:var(--faint);cursor:text;padding:11px 13px;border:1px dashed var(--line-3);border-radius:var(--r-md);transition:var(--dur-fast)}

.desc-empty:hover{border-color:var(--accent);color:var(--muted)}

.rich-hint{font-size:var(--t-xs);color:var(--faint);margin-top:5px;line-height:1.4}

.rich-p{margin:0 0 7px}

.rich-p:last-child{margin-bottom:0}

.rich-list{margin:2px 0 8px;padding-left:20px}

.rich-list li{margin:2px 0}

.desc-rendered code,.comment-text code{font-family:var(--mono);font-size:.88em;background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-xs);padding:1px 5px}

.desc-rendered strong,.comment-text strong{font-weight:700;color:var(--ink)}

.desc-rendered a,.comment-text a{color:var(--accent);text-decoration:none}

.desc-rendered a:hover,.comment-text a:hover{text-decoration:underline}

.comment-text .rich-p{margin:0 0 4px}

.comment-text .rich-list{margin:2px 0 4px}
/* ==== features.015.css ==== */
.subtask{display:block;padding:2px 4px;border-bottom:1px solid var(--line-2);cursor:grab}

.subtask.dragging{opacity:.45;cursor:grabbing}
/* ==== utilities.043.css ==== */
.sub-check{width:17px;height:17px;border-radius:50%;border:1.5px solid var(--line-3);flex-shrink:0;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:var(--dur-fast)}

.sub-check svg{opacity:0;color:var(--on-solid)}
/* ==== features.016.css ==== */
.subtask.done .sub-check{background:var(--ok);border-color:var(--ok)}

.subtask.done .sub-check svg{opacity:1}
/* ==== utilities.044.css ==== */
.sub-name{flex:1;font-size:var(--t-body);border:none;background:transparent;outline:none}
/* ==== features.017.css ==== */
.subtask.done .sub-name{color:var(--faint);text-decoration:line-through}
/* ==== utilities.045.css ==== */
.sub-del{opacity:0;width:24px;height:24px;border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;color:var(--faint)}
/* ==== features.018.css ==== */
.subtask:hover .sub-del{opacity:1}
/* ==== utilities.046.css ==== */
.sub-del:hover{background:var(--danger-soft);color:var(--danger)}

/* строка подзадачи — сама раскладка вынесена из .subtask, т.к. .subtask
   теперь обёртка вокруг строки и необязательной заметки под ней */
.sub-main{display:flex;align-items:center;gap:8px;padding:6px 0}

.sub-drag{width:16px;height:16px;display:flex;align-items:center;justify-content:center;color:var(--line-3);flex-shrink:0;opacity:0;cursor:grab;transition:opacity var(--dur-instant),color var(--dur-instant)}
/* ==== features.019.css ==== */
.subtask:hover .sub-drag{opacity:1}
/* ==== utilities.047.css ==== */
.sub-drag:hover{color:var(--muted)}

.sub-mini.has-notes{opacity:1;color:var(--accent)}

.sub-notes-area{
  display:none;width:100%;min-height:34px;margin:0 0 8px 40px;padding:7px 10px;
  border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface-2);
  font-size:var(--t-sm);line-height:1.5;color:var(--ink-2);resize:vertical;outline:none;
  font-family:inherit;transition:border-color var(--dur-fast),background var(--dur-fast);
}

.sub-notes-area:focus{border-color:var(--accent);background:var(--surface)}
/* ==== features.020.css ==== */
.subtask.notes-open .sub-notes-area{display:block}
/* ==== utilities.048.css ==== */
.add-sub{display:flex;align-items:center;gap:10px;padding:9px 4px;color:var(--faint);font-size:var(--t-body);cursor:text}
/* ==== components.029.css ==== */
.add-sub input{flex:1;border:none;background:transparent;outline:none;font-size:var(--t-body)}
/* ==== utilities.049.css ==== */
.add-sub:hover{color:var(--accent)}

/* activity / comments */
.activity{margin-top:8px}

.comment{display:flex;gap:11px;margin-bottom:16px}

.comment-avwrap{flex-shrink:0}

.comment-body{flex:1;min-width:0}

.comment-head{display:flex;align-items:baseline;gap:8px;margin-bottom:3px}

/* --- Реакции, ответы, «решено» -------------------------------- */
.cm-rx-row{display:flex;gap:5px;flex-wrap:wrap;margin-top:7px}

.cm-rx{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:var(--r-pill);
  border:1px solid var(--line);background:var(--surface-2);font-size:var(--t-sm);cursor:pointer;transition:var(--dur-instant)}

.cm-rx:hover{border-color:var(--line-3)}

.cm-rx.on{background:var(--accent-soft);border-color:var(--accent-line);color:var(--accent-700);font-weight:600}

.cm-rx span{font-size:var(--t-micro);font-weight:700}
/* ==== components.030.css ==== */
.menu-rx{display:flex;gap:2px;padding:4px}

.menu-rx .menu-item{padding:6px 8px;border-radius:var(--r-sm)}
/* ==== utilities.050.css ==== */
/* Цитата исходного сообщения: короткая, кликабельная, приглушённая —
   она указывает на контекст, а не соревнуется с самим ответом. */
.cm-quote{display:flex;gap:6px;align-items:baseline;margin:4px 0 6px;padding:5px 9px;
  border-left:2px solid var(--line-3);background:var(--surface-2);border-radius:0 var(--r-xs) var(--r-xs) 0;
  font-size:var(--t-xs);color:var(--muted);cursor:pointer;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.cm-quote:hover{border-left-color:var(--accent)}

.cm-quote-a{font-weight:700;color:var(--ink-2);flex-shrink:0}

.cm-child{margin-left:22px}

/* Решённый комментарий гаснет, но остаётся: история не переписывается. */
.cm-done .comment-text{opacity:.6}

.cm-done-tag{display:inline-flex;align-items:center;gap:3px;margin-left:6px;padding:1px 7px;
  border-radius:var(--r-pill);background:var(--ok-soft);color:var(--ok);font-size:var(--t-micro);font-weight:700}

.comment-act.on{color:var(--ok)}

.cm-flash{animation:cmFlash 1.2s ease-out}

@keyframes cmFlash{0%{background:var(--accent-soft)}100%{background:transparent}}

.cm-replybar{display:flex;align-items:center;gap:7px;margin-bottom:6px;padding:6px 10px;
  border-radius:var(--r-sm);background:var(--accent-soft);color:var(--accent-700);
  font-size:var(--t-xs);font-weight:600}

.cm-replybar span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.cm-replyx{color:inherit;opacity:.7;cursor:pointer;display:flex}

.cm-replyx:hover{opacity:1}

@media(max-width:768px){.cm-child{margin-left:12px}.cm-rx{min-height:32px}}

.comment-actions{margin-left:auto;display:flex;gap:2px;opacity:0;transition:opacity var(--dur-instant)}

.comment:hover .comment-actions{opacity:1}

.comment-act{width:24px;height:24px;border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;color:var(--faint);flex-shrink:0}

.comment-act:hover{background:var(--surface-3);color:var(--ink)}

.comment-author{font-weight:600;font-size:var(--t-body)}

.comment-time{font-size:var(--t-xs);color:var(--faint);font-family:var(--mono)}

.comment-text{font-size:var(--t-body);line-height:1.5;color:var(--ink-2)}

.comment-edit-area{width:100%;min-height:52px;padding:8px 10px;border:1px solid var(--accent);border-radius:var(--r-sm);background:var(--surface-2);font-size:var(--t-body);line-height:1.5;color:var(--ink);resize:vertical;outline:none;font-family:inherit}

.comment-edit-actions{display:flex;gap:8px;margin-top:8px}

.comment-box{display:flex;gap:11px;margin-top:8px}
/* ==== components.031.css ==== */
.comment-input-wrap{flex:1;border:1px solid var(--line);border-radius:var(--r-md);background:var(--surface-2);overflow:hidden;transition:var(--dur-fast)}

.comment-input-wrap:focus-within{border-color:var(--accent);background:var(--surface);box-shadow:var(--ring)}

.comment-input{width:100%;padding:11px 13px;border:none;background:transparent;outline:none;font-size:var(--t-body);resize:none;min-height:42px}
/* ==== utilities.051.css ==== */
.comment-actions{display:flex;justify-content:flex-end;padding:0 10px 10px}
/* ==== components.032.css ==== */
/* ============================================================ MODAL */
#modalRoot{position:fixed;inset:0;z-index:80;display:none;align-items:flex-start;justify-content:center;padding:9vh 20px}

#modalRoot.show{display:flex}

.modal-back{position:absolute;inset:0;background:rgba(15,16,32,.42);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}

[data-theme="dark"] .modal-back{background:rgba(0,0,0,.66)}

.modal{position:relative;width:min(500px,100%);background:var(--raised);border:1px solid var(--line);border-radius:var(--r-xl);box-shadow:var(--shadow-lg),inset 0 1px 0 var(--edge-hi);overflow:hidden;animation:pop .22s cubic-bezier(.34,1.3,.64,1);
  /* Раньше высота модалки ничем не ограничивалась ни на одном
     размере экрана шире мобильного (у мобильной версии — свой,
     уже верный вариант ниже в @media(max-width:768px), нижний шит
     с max-height:92dvh). На desktop/tablet/ноутбуке с невысоким
     окном браузера длинная форма (например, создание проекта с
     пользовательскими полями) просто продолжалась за нижний край
     экрана — без скролла внутри и без возможности вообще увидеть
     кнопку подтверждения. Тот же приём, что уже применён к
     мобильному варианту: сама модалка — колонка ограниченной
     высоты, шапка и футер остаются на месте, прокручивается только
     .modal-body. */
  max-height:82vh;display:flex;flex-direction:column;
}
/* ==== utilities.052.css ==== */
@keyframes pop{from{opacity:0;transform:translateY(12px) scale(.975)}to{opacity:1;transform:none}}
/* ==== components.033.css ==== */
.modal-head{display:flex;align-items:center;gap:10px;padding:20px 22px 4px;flex:none}

.modal-title{font-size:var(--t-h2);font-weight:700;letter-spacing:-.025em;color:var(--ink)}

.modal-x{margin-left:auto;width:30px;height:30px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;color:var(--muted);transition:var(--dur-instant)}

.modal-x:hover{background:var(--surface-3);color:var(--ink)}

.modal-body{padding:16px 22px 22px;overflow-y:auto;min-height:0}

.modal-foot{display:flex;gap:9px;justify-content:flex-end;padding:14px 22px;border-top:1px solid var(--line);background:var(--surface-2);flex:none}

.form-row{margin-bottom:18px}
/* ==== utilities.053.css ==== */
/* Раскрывающийся блок необязательных полей формы: закрыт по
   умолчанию, поэтому форма начинается с того, что действительно
   нужно заполнить, но ничего не прячет безвозвратно. */
/* Три числа в карточке «О проекте». Раньше та же вёрстка была
   набрана инлайновыми стилями прямо в строке разметки — из-за
   этого её нельзя было ни поправить в одном месте, ни повторить
   без копирования. Теперь это обычный компонент, как остальные. */
.ov-stats{display:flex;gap:10px;margin-top:14px}

.ov-stat{flex:1;min-width:0;padding:14px;border:1px solid var(--line);border-radius:var(--r-md);background:var(--surface-2)}

.ov-stat-n{font-size:24px;font-weight:700;line-height:1.1}

.ov-stat-l{font-size:var(--t-sm);color:var(--muted);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

@media(max-width:520px){.ov-stats{gap:8px}.ov-stat{padding:11px}.ov-stat-n{font-size:var(--t-lg)}}
/* ==== components.034.css ==== */
/* ============================================================
   УСТОЙЧИВОСТЬ К ДЛИНЕ ТЕКСТА (финальная полировка)
   Одна и та же подпись в трёх языках отличается по длине очень
   заметно: «Панель» — «Gösterge paneli», «Срок» — «Bitiş tarihi»,
   «Готово» — «Tamamlandı». Раньше это лечилось бы подгонкой ширин
   под самый длинный вариант, но тогда русский и английский
   получают пустоту, а любое новое слово снова ломает раскладку.
   Вместо этого — общее правило: имена, которые вводит человек,
   и подписи, которые приходят из перевода, обрезаются многоточием
   и не выталкивают соседей. Ни один блок не «поедет» от того, что
   слово оказалось на пять букв длиннее ожидаемого. */
.pc-name,.arc-name,.section-title,.doc-row-title,.trash-name,.fld-name,
.goal-card-title,.file-card-name,.sg-t{
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%;min-width:0;
}
/* ==== utilities.054.css ==== */
/* Название проекта в шапке: обрезается, но не сжимает кнопки рядом. */
.ph-title{gap:11px}

.ph-title>span:not(.ph-emoji):not(.hdr-stu){min-width:0}

.ph-emoji,.hdr-stu,.ph-title .tb-icon{flex-shrink:0}
/* ==== features.021.css ==== */
/* Ячейки таблиц (список задач, портфель) — grid-элементы по
   умолчанию не сжимаются меньше содержимого, отсюда «выезжающие»
   колонки на длинных значениях. */
.task-row>div,.list-colhead>span,.pf-row>div,.pf-name{min-width:0}
/* ==== utilities.055.css ==== */
.pf-name>span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* ==== features.022.css ==== */
/* Строки-карточки: текстовая часть уступает место кнопкам,
   а не наоборот. */
.arc-main,.trash-main,.doc-row-main{min-width:0;flex:1}
/* ==== components.035.css ==== */
.arc-row>.btn,.trash-row>.btn,.doc-row-del{flex-shrink:0}

/* Заголовки колонок и подписи чипов не переносятся посреди слова. */
.chip,.tab{max-width:100%}
/* ==== utilities.056.css ==== */
.chip{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* Поле переименования на месте: намеренно наследует размер и
   начертание того текста, который заменяет, чтобы строка не
   «прыгала» в момент перехода в режим правки. */
.rename-inp{font:inherit;color:inherit;background:var(--surface);border:1px solid var(--accent);border-radius:var(--r-xs);padding:1px 6px;outline:none;box-shadow:var(--ring);min-width:120px}

.rename-inp-proj{font-size:var(--t-display);font-weight:700;letter-spacing:-.032em;max-width:min(560px,60vw)}

.rename-inp-sec{font-size:var(--t-body);font-weight:700;max-width:320px}

.rename-inp-grp{font-size:var(--t-sm);font-weight:600;max-width:100%;min-width:0;flex:1}
/* ==== components.036.css ==== */
.form-more{margin:-4px 0 14px;border-top:1px solid var(--line-2);padding-top:12px}

.tpl-picker-btn{display:flex;align-items:center;justify-content:space-between;cursor:pointer;text-align:left;color:var(--ink)}

.tpl-picker-btn:hover{border-color:var(--line-2)}

.tpl-picker-btn svg{color:var(--faint);flex-shrink:0}

.form-more-sum{cursor:pointer;list-style:none;font-size:var(--t-sm);font-weight:600;color:var(--muted);display:inline-flex;align-items:center;gap:6px;user-select:none;padding:2px 0}

.form-more-sum::-webkit-details-marker{display:none}

.form-more-sum::before{content:'';width:0;height:0;border-left:5px solid currentColor;border-top:4px solid transparent;border-bottom:4px solid transparent;transition:transform var(--dur-fast)}

.form-more[open] .form-more-sum::before{transform:rotate(90deg)}

.form-more-sum:hover{color:var(--ink-2)}

.form-more>.form-row:first-of-type{margin-top:12px}

/* ============================================================
   ФОРМЫ БЕЗ АНКЕТНОГО ВИДА (дружелюбный облик)
   Подписи полей были такими же тёмными и полужирными, как сами
   значения, поэтому форма читалась как бланк: половина текста —
   вопросы, половина — ответы, и глазу негде отдохнуть. Подпись
   служебная, она нужна один раз при первом взгляде; значение —
   главное. Разводим их по весу и цвету, а поля делаем выше и
   мягче, чтобы форма дышала. */
.form-lbl{display:block;font-size:var(--t-sm);font-weight:500;color:var(--muted);margin-bottom:6px}

.form-input{width:100%;height:var(--ctl-h-lg);padding:0 13px;border:1px solid var(--line);border-radius:var(--r-ctl);font-size:var(--t-h3);background:var(--surface-2);transition:var(--dur-fast)}

textarea.form-input{height:auto;padding:10px 12px}

.form-input::placeholder{color:var(--faint)}

.form-input:focus{outline:none;border-color:var(--accent);background:var(--surface);box-shadow:var(--ring)}

.form-input:disabled{opacity:.55;cursor:not-allowed;background:var(--well)}
/* ==== utilities.057.css ==== */
.swatch-row{display:flex;gap:9px;flex-wrap:wrap}

.swatch{width:30px;height:30px;border-radius:var(--r-sm);cursor:pointer;position:relative;transition:transform var(--dur-instant);box-shadow:inset 0 0 0 1px rgba(0,0,0,.08),inset 0 1px 0 rgba(255,255,255,.2)}

.swatch:hover{transform:scale(1.1)}

.swatch.sel::after{content:"";position:absolute;inset:-3px;border:2px solid var(--accent);border-radius:var(--r-md)}

.emoji-row{display:flex;gap:6px;flex-wrap:wrap}

.emoji-pick{width:38px;height:38px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;font-size:var(--t-lg);cursor:pointer;background:var(--surface-2);border:1px solid var(--line);transition:var(--dur-instant)}

.emoji-pick:hover{background:var(--surface-3);border-color:var(--line-3)}

.emoji-pick.sel{border-color:var(--accent);background:var(--accent-soft);box-shadow:var(--ring)}
/* ==== components.037.css ==== */
/* выпадающее меню — самый верхний слой, с размытием подложки */
.menu{position:fixed;z-index:90;background:var(--raised);border:1px solid var(--line);border-radius:var(--r-md);box-shadow:var(--shadow-lg),inset 0 1px 0 var(--edge-hi);padding:6px;min-width:200px;max-width:calc(100vw - 16px);animation:pop .13s ease}

.menu-item{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:var(--r-xs);font-size:var(--t-body);font-weight:500;color:var(--ink-2);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:background var(--dur-instant),color var(--dur-instant)}

.menu-item:hover{background:var(--surface-3);color:var(--ink)}

.menu-item svg{width:16px;height:16px;color:var(--faint)}

.menu-item:hover svg{color:var(--muted)}

.menu-item.danger{color:var(--danger)}

.menu-item.danger svg{color:var(--danger)}

.menu-item.danger:hover{background:var(--danger-soft);color:var(--danger)}

.menu-item.sel{color:var(--accent-700);font-weight:600}

[data-theme="dark"] .menu-item.sel{color:var(--accent-600)}

.menu-item .mtick{margin-left:auto;color:var(--accent)}

.menu-sep{height:1px;background:var(--line);margin:6px 4px}

/* Подпись контекста в меню создания: где именно появится объект.
   Приглушена и не переносится — она уточняет, а не спорит с
   названием пункта за внимание. */
.menu-sub{display:block;font-size:var(--t-micro);color:var(--faint);font-weight:500;
  margin-top:1px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:230px}

/* Недоступный пункт не прячем, а объясняем: исчезнувший пункт
   человек считает пропавшей возможностью и идёт её искать. */
.menu-item-off{display:flex;align-items:flex-start;gap:10px;padding:8px 12px;
  color:var(--faint);cursor:default;opacity:.75}

.menu-item-off svg{flex-shrink:0;margin-top:1px}

.menu-head{font-size:var(--t-xs);font-weight:600;color:var(--faint);padding:9px 10px 5px}
/* ==== utilities.058.css ==== */
.opt-dot{width:11px;height:11px;border-radius:50%;flex-shrink:0}
/* ==== components.038.css ==== */
/* toast */
#toastRoot{position:fixed;bottom:22px;left:50%;transform:translateX(-50%);z-index:100;display:flex;flex-direction:column;gap:8px;align-items:center;pointer-events:none}

.toast{display:flex;align-items:center;gap:10px;background:var(--ink);color:var(--canvas);padding:12px 17px;border-radius:var(--r-md);box-shadow:var(--shadow-lg);font-size:var(--t-body);font-weight:500;pointer-events:auto;animation:toastIn .25s cubic-bezier(.34,1.4,.64,1)}

[data-theme="dark"] .toast{background:var(--surface-3);color:var(--ink);border:1px solid var(--line-3);box-shadow:var(--shadow-lg),inset 0 1px 0 rgba(255,255,255,.06)}

.toast svg{width:17px;height:17px;color:var(--accent-600)}

.toast .undo{margin-left:6px;color:var(--accent-600);font-weight:600;cursor:pointer;padding-left:6px;border-left:1px solid rgba(255,255,255,.2)}

@keyframes toastIn{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
/* ==== utilities.059.css ==== */
/* empty state */
/* --- Скелет загрузки ------------------------------------------
   Пульсация приглушённая и медленная: индикатор должен сообщать
   «идёт работа», а не тянуть взгляд на себя, пока человек ждёт. */
.sk-wrap{display:flex;flex-direction:column;gap:14px;padding:6px 0}

.sk-row{display:flex;align-items:center;gap:12px}

.sk-dot{width:30px;height:30px;border-radius:50%;background:var(--surface-3);flex-shrink:0;animation:skPulse 1.5s ease-in-out infinite}

.sk-lines{flex:1;min-width:0;display:flex;flex-direction:column;gap:7px}

.sk-line{height:9px;border-radius:var(--r-xs);background:var(--surface-3);animation:skPulse 1.5s ease-in-out infinite}

.sk-line-2{height:7px;opacity:.6}

.sk-row:nth-child(2) .sk-dot,.sk-row:nth-child(2) .sk-line{animation-delay:.12s}

.sk-row:nth-child(3) .sk-dot,.sk-row:nth-child(3) .sk-line{animation-delay:.24s}

.sk-row:nth-child(4) .sk-dot,.sk-row:nth-child(4) .sk-line{animation-delay:.36s}

@keyframes skPulse{0%,100%{opacity:.5}50%{opacity:1}}

/* Кнопка следующего шага в пустом состоянии — чтобы экран без
   содержимого не был тупиком. */
.empty-cta{margin-top:18px}

.err-ic{color:var(--danger)}

.err-state .empty-ic{background:var(--danger-soft)}

.empty-state{text-align:center;padding:72px 20px;color:var(--faint)}

.empty-ic{width:66px;height:66px;margin:0 auto 18px;border-radius:var(--r-xl);background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-sm),inset 0 1px 0 var(--edge-hi);display:flex;align-items:center;justify-content:center;color:var(--faint)}

.empty-title{font-size:var(--t-h2);font-weight:700;color:var(--ink);margin-bottom:7px;letter-spacing:-.025em}

.empty-desc{font-size:var(--t-body);max-width:320px;margin:0 auto 20px;line-height:1.6}

/* misc */
.spin{width:16px;height:16px;border:2px solid var(--line-3);border-top-color:var(--accent);border-radius:50%;animation:spin .7s linear infinite}

@keyframes spin{to{transform:rotate(360deg)}}

/* responsive */
@media(max-width:900px){
  #app{grid-template-columns:var(--sidebar-w-collapsed) 1fr}
  .home-grid{grid-template-columns:1fr}
  .stat-card{grid-column:span 6}
  .chart-card.half,.chart-card.third{grid-column:span 12}
  .list-colhead,.task-row{grid-template-columns:1fr 120px 90px}
  .list-colhead .ch:nth-child(4),.list-colhead .ch:nth-child(5),
  .task-row>*:nth-child(4),.task-row>*:nth-child(5){display:none}
}

@media(max-width:640px){
  :root{--gutter:16px}
  .page-head,.view-toolbar,.list-wrap,.board-wrap,.cal-wrap,.dash-wrap,.home-wrap,.goals-wrap,.pf-wrap,.inbox-wrap,.st-page,.st-head{padding-left:var(--gutter);padding-right:var(--gutter)}
  .ph-title{font-size:var(--t-h1)}
  .panel-name{font-size:var(--t-h1)}
  .tb-search{display:none}
  /* Кнопка-триггер мобильного поиска показывается на той же ширине,
     на которой прячется обычная строка поиска (см. правило выше) —
     раньше кнопка появлялась уже при 900px, а .tb-search скрывалась
     только при 640px: в промежутке 641–900px (типичный планшет/
     суженное окно на ноутбуке) на панели одновременно были видны и
     полноразмерное поле поиска, и отдельная кнопка для его открытия
     — то есть две точки входа в одно и то же действие. Один и тот же
     порог для обеих половин одного и того же поведения. */
  .tb-only-mobile{display:inline-flex}
}

/* ============================================================
   МОБИЛЬНАЯ АДАПТИВНОСТЬ (проверено на 390px и 360px)
   Правки по итогам измерений: поиск, календарь, доска,
   размеры тач-целей, зум полей на iOS, безопасные зоны.
   ============================================================ */
.tb-only-mobile{display:none}
/* ==== features.023.css ==== */
.tb-search-x{display:none}
/* ==== utilities.060.css ==== */
@media(max-width:900px){
  /* --- Поиск: на узком экране прячется за кнопку и разворачивается поверх ---
     Сама видимость кнопки-триггера теперь задаётся выше, в блоке
     max-width:640px, вместе с правилом, которое прячет обычное поле
     поиска — оба конца одного и того же переключения в одном месте.
     Здесь остаётся только поведение оверлея (что происходит, когда
     класс .search-open уже стоит на #topbar), которое актуально в
     любом случае, на какой бы ширине действие ни было вызвано. */
  #topbar.search-open .tb-search{
    display:flex;align-items:center;position:absolute;left:8px;right:8px;top:50%;
    transform:translateY(-50%);width:auto;z-index:30;background:var(--surface);
    border-radius:var(--r-md);box-shadow:0 4px 18px rgba(0,0,0,.22)}
  #topbar.search-open .tb-search input{height:40px;font-size:var(--t-h2);padding-right:38px}
  #topbar.search-open .tb-search-x{
    display:flex;align-items:center;justify-content:center;position:absolute;right:4px;top:50%;
    transform:translateY(-50%);width:34px;height:34px;border:0;background:transparent;
    color:var(--muted);border-radius:var(--r-sm);cursor:pointer}
  #topbar.search-open .tb-burger,
  #topbar.search-open .tb-create,
  #topbar.search-open .tb-right{visibility:hidden}

  /* --- Поля ввода: 16px, иначе iOS увеличивает страницу при фокусе --- */
  input,select,textarea,.form-input,.pp-input,.asg-input,.add-task-input,.comment-input{font-size:var(--t-h2)!important}
  .tb-search input{font-size:var(--t-h2)}

  /* --- Топбар: убираем лишнее, чтобы правая группа влезала --- */
  #topbar{gap:4px;padding:0 8px;overflow:hidden}
  .tb-right{gap:2px;margin-left:auto;flex-shrink:1;min-width:0}
  .tb-sync .tb-sync-lbl{display:none}
  .tb-create{padding:0 12px;white-space:nowrap}

  /* --- Виджеты Главной: одна колонка, ничего не шире экрана --- */
  .home-grid{grid-template-columns:1fr!important}
  .widget,.widget.wide{grid-column:auto!important;max-width:100%;min-width:0}
  .home-wrap,.home-hero{max-width:100%}
  .home-tabs{overflow-x:auto;scrollbar-width:none;max-width:100%}
  .home-tabs::-webkit-scrollbar{display:none}
  .home-tab{flex:0 0 auto}
  .mini-task{max-width:100%;min-width:0}

  /* --- Тач-цели: минимум 40px по высоте --- */
  .nav-item,.proj-item,.side-invite{min-height:42px}
  .tb-icon,.tb-burger{min-width:40px;min-height:40px}
  .home-tab{min-height:38px;padding:8px 14px}
  .tab{min-height:42px}
  .chip{min-height:34px}
  .menu-item{min-height:42px;display:flex;align-items:center}
  .st-tab{min-height:42px}
  /* галочка задачи: сама метка 26px, но кликаемая зона больше за счёт отступа */
  .task-check,.card-check{min-width:26px;min-height:26px;padding:8px;margin:-8px;box-sizing:content-box}
  .nav-label .add{width:34px;height:34px;margin-right:-4px}
  .brand{min-height:40px}
  .sub-check{min-width:24px;min-height:24px}
  .dep-del,.tag-x,.pp-x{min-width:30px;min-height:30px}

  /* --- Доска: колонка почти во весь экран + прилипание при пролистывании --- */
  .board-wrap{scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;
    padding:14px 12px 32px;gap:10px}
  .board-col{scroll-snap-align:center;width:84vw!important;min-width:84vw}
  .board-addcol{width:84vw!important;min-width:84vw}

  /* --- Вкладки проекта: скроллятся внутри своей ширины и не распирают страницу --- */
  .tabs{-webkit-overflow-scrolling:touch;scrollbar-width:none;
    overflow-x:auto;max-width:100%;flex-wrap:nowrap}
  .tabs::-webkit-scrollbar{display:none}
  .tab{flex:0 0 auto}
  /* общий предохранитель: ничего не шире экрана */
  #main,.page,.page-head,.dash-wrap,.chart-card{max-width:100%;min-width:0}
  .chart-card{overflow:hidden}

  /* --- Хронология: горизонтальная прокрутка пальцем --- */
.timeline{-webkit-overflow-scrolling:touch}
}

@media(max-width:640px){
  /* --- Статистика Home: 4 в ряд слишком тесно на телефоне (иконка +
     двузначное число + подпись едва помещаются) — та же сетка,
     переставленная в 2×2, каждая ячейка вдвое шире. --- */
  .home-stats{grid-template-columns:repeat(2,1fr)}

  /* --- Календарь: сетка 7 колонок нечитаема на телефоне (ячейка ~50px),
         поэтому дни идут списком сверху вниз --- */
  .cal-grid{display:block!important;overflow:visible;min-width:0!important;width:auto}
  .cal-dow{display:none}
  .cal-wrap,.cal-scroll{overflow:visible!important;min-width:0!important}
  .cal-cell{width:auto!important;min-height:0!important;border:0;
    border-bottom:1px solid var(--line);padding:10px 13px}
  .cal-cell.other{display:none}
  .cal-cell.today{background:var(--accent-soft)}
  .cal-daynum{font-size:var(--t-sm);font-weight:700;color:var(--ink);margin-bottom:5px}
  .cal-cell.today .cal-daynum{color:var(--accent)}
  .cal-ev{white-space:normal;font-size:var(--t-body);padding:7px 9px;margin-bottom:4px}
  .cal-more{font-size:var(--t-sm);padding:4px 0}

  /* --- Панель задачи: полноэкранная, поля в столбик --- */
  #panel{width:100vw!important;max-width:100vw}
  .field-lbl{color:var(--faint);font-size:var(--t-xs)}
  .panel-body{padding-bottom:calc(24px + env(safe-area-inset-bottom))}

  /* --- Модальные окна: во всю ширину, с отступом снизу --- */
  .modal{width:calc(100vw - 20px)!important;max-width:calc(100vw - 20px);
    max-height:calc(100vh - 80px);overflow-y:auto}
  .modal-lg{width:calc(100vw - 20px)!important}
  .modal-foot{position:sticky;bottom:0;background:var(--surface);
    padding-bottom:calc(12px + env(safe-area-inset-bottom))}

  /* --- Меню: не уже пальца, не шире экрана --- */
  .menu{max-width:calc(100vw - 16px)}
  .pp-pop{width:calc(100vw - 24px)}

  /* --- Отчёты и панель: диаграммы в одну колонку --- */
  .dash-wrap{grid-template-columns:1fr!important}
  .chart-card.half,.chart-card.third,.chart-card.full{grid-column:auto!important}
  .stat-card{padding:14px 15px}
  .stat-value{font-size:26px}

  /* --- Шапка проекта: заголовок и кнопки в столбик --- */
  .ph-top{flex-direction:column;align-items:flex-start;gap:10px}
  .ph-actions{width:100%;flex-wrap:wrap}
  .page-head{padding-bottom:10px}

  /* --- Шапка профиля: на телефоне это не сжатый десктоп-ряд, а
     центрированная колонка — аватар сверху, имя/подпись/чипы под
     ним. При 92px аватаре и 26px имени рядом почти не остаётся
     места уже на 375px экране, а длинный email в .prof-sub (одна
     неразрывная строка) раздвигал бы шапку вбок без переноса. --- */
  .prof-head{flex-direction:column;text-align:center;gap:10px}
  .prof-chips{justify-content:center}

  /* --- Настройки: вкладки прокручиваются --- */
  .st-tabs{overflow-x:auto;scrollbar-width:none}
  .st-tabs::-webkit-scrollbar{display:none}
  .st-section{padding:16px 15px}

  /* --- Онбординг и карточки --- */
  .ob-card{padding:15px 16px}
  .home-hero{padding:16px 15px}
}

/* Очень узкие экраны (360px и меньше) */
@media(max-width:380px){
  .tb-create span,.tb-create{font-size:var(--t-sm)}
  .board-col,.board-addcol{width:88vw!important;min-width:88vw}
  .stat-value{font-size:var(--t-h1)}
}

/* Горизонтальная ориентация телефона: экономим высоту */
@media(max-height:480px) and (orientation:landscape){
  #topbar{height:46px}
  .modal{max-height:calc(100vh - 40px)}
}

@media(prefers-reduced-motion:reduce){
  *{animation-duration:.01ms!important;transition-duration:.01ms!important}
  /* ============================================================
     ИСКЛЮЧЕНИЕ ДЛЯ ИНДИКАТОРОВ СОСТОЯНИЯ
     Правило выше гасит анимации ради тех, кому движение мешает, —
     и правильно делает: подпрыгивания, скольжения и пульсации
     декоративны. Но под ту же гребёнку попадал вращающийся
     индикатор загрузки, а он не украшение, а единственный признак,
     что операция идёт. Замерший спиннер сообщает ровно обратное —
     «всё встало». Функциональным индикаторам движение возвращаем,
     но замедленным: оно считывается как работа, а не мельтешит. */
  .print-spin{animation-duration:1.8s!important}
  .sk-dot,.sk-line{animation:none!important;opacity:.7}
}
/* ==== components.039.css ==== */
/* ===== dependencies / followers / milestones / status ===== */
/* ============================================================
   ЗНАЧКИ, КОТОРЫЕ ЧИТАЮТСЯ САМИ (без обучения)
   Здесь стояли ромб «◆», стрелка «↻» и пульсирующая точка —
   каждому требовалась всплывающая подсказка, а одной из них
   подсказка из семи слов: «Изменение сохранено локально, ждёт
   подтверждения сервером». Подсказка — это признак того, что
   элемент не справился: её не видно на телефоне, где нет курсора,
   её не читает тот, кто не догадался задержать мышь, и она не
   помогает в тот момент, когда взгляд скользит по списку. Значки
   заменены короткими словами в таблетке: место занимают чуть
   больше, зато объяснять нечего. */
.ms-badge,.recur-badge,.row-unsynced,.blocked-badge,.sec-lock,.timer-badge{
  display:inline-flex;align-items:center;gap:4px;flex-shrink:0;
  font-size:var(--t-micro);font-weight:600;line-height:1;
  padding:3px 7px;border-radius:var(--r-pill);white-space:nowrap;
}

.ms-badge{color:var(--warn);background:var(--warn-soft)}

.blocked-badge{color:var(--danger);background:var(--danger-soft)}

.blocked-badge svg{width:12px;height:12px}
/* ==== utilities.061.css ==== */
.fol-row{display:flex;align-items:center;gap:4px;flex-wrap:wrap}

.fol-av{cursor:pointer;display:inline-flex;border-radius:50%;transition:var(--dur-instant)}

.fol-av:hover{opacity:.5;transform:scale(.93)}

.fol-add{width:24px;height:24px;border-radius:50%;border:1.4px dashed var(--line-3);color:var(--muted);display:flex;align-items:center;justify-content:center;flex-shrink:0}

.fol-add:hover{border-color:var(--accent);color:var(--accent)}

.deps-list{display:flex;flex-direction:column;gap:6px;margin-bottom:8px}

.dep-item{display:flex;align-items:center;gap:9px;padding:8px 11px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface-2);font-size:var(--t-body)}

.dep-dot{width:9px;height:9px;border-radius:50%;background:var(--warn);flex-shrink:0}

.dep-dot.done{background:var(--ok)}

.dep-name{flex:1;cursor:pointer;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.dep-name:hover{color:var(--accent)}

.dep-del{width:22px;height:22px;border-radius:var(--r-xs);color:var(--muted);display:flex;align-items:center;justify-content:center;flex-shrink:0}

.dep-del:hover{background:var(--danger-soft);color:var(--danger)}
/* ==== components.040.css ==== */
.add-dep-btn{display:inline-flex;align-items:center;gap:6px;font-size:var(--t-body);color:var(--accent);font-weight:600;padding:6px 2px}

.add-dep-btn:hover{opacity:.8}
/* ==== utilities.062.css ==== */
.dep-warn{display:flex;align-items:center;gap:6px;margin:2px 8px 6px;padding:7px 9px;
  border-radius:var(--r-sm);background:var(--warn-soft);color:var(--warn);
  font-size:var(--t-xs);font-weight:600;line-height:1.35}

.dep-warn svg{flex-shrink:0}

.dep-blocks{font-size:var(--t-sm);color:var(--muted);margin-top:8px}

.dep-blocks span{cursor:pointer;color:var(--ink-2)}

.dep-blocks span:hover{color:var(--accent)}

.dep-blocks span:focus-visible{outline:none;color:var(--accent);text-decoration:underline}

.dep-name:focus-visible{outline:none;color:var(--accent);text-decoration:underline}

.hdr-stu{display:inline-flex;align-items:center;gap:6px;font-size:var(--t-sm);font-weight:600;padding:4px 10px;border-radius:var(--r-pill);margin-left:10px;cursor:pointer;vertical-align:middle}
/* ==== components.041.css ==== */
.status-card{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}
/* ==== utilities.063.css ==== */
.sc-left{flex:1;min-width:0}

.sc-pill{display:inline-flex;align-items:center;gap:7px;font-size:var(--t-sm);font-weight:600;padding:5px 12px;border-radius:var(--r-pill);margin:8px 0 10px}

.sc-text{font-size:var(--t-h3);line-height:1.55;color:var(--ink-2);margin:0}

.sc-meta{display:flex;align-items:center;gap:7px;font-size:var(--t-sm);color:var(--muted);margin-top:12px}

.stu-opt{width:100%}
/* ==== components.042.css ==== */
/* ===== custom fields ===== */
.cf-cell-btn{cursor:pointer;display:inline-flex;align-items:center;max-width:100%}

.cf-cell-btn:hover{opacity:.85}
/* ==== utilities.064.css ==== */
.cf-val{font-size:var(--t-body);color:var(--ink-2);font-family:var(--mono);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.cf-ch{cursor:pointer}

.cf-ch:hover{color:var(--accent)}

.fld-list{display:flex;flex-direction:column;margin-bottom:4px}

.fld-row{display:flex;align-items:center;gap:10px;padding:9px 2px;border-bottom:1px solid var(--line-2)}

.fld-name{flex:1;font-weight:600;font-size:var(--t-body)}

.fld-type{font-size:var(--t-sm);color:var(--muted)}
/* ==== components.043.css ==== */
.modal-sub{font-size:var(--t-xs);font-weight:600;color:var(--faint);margin:14px 0 10px}

select.form-input{appearance:auto;cursor:pointer}
/* ==== utilities.065.css ==== */
/* ===== rich subtasks + attachments ===== */
.sub-mini{width:24px;height:24px;border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;color:var(--faint);flex-shrink:0;opacity:0;cursor:pointer}
/* ==== features.024.css ==== */
.subtask:hover .sub-mini{opacity:1}
/* ==== utilities.066.css ==== */
.sub-mini:hover{background:var(--surface);color:var(--accent)}

.sub-av{cursor:pointer;flex-shrink:0;display:inline-flex}

.sub-av:hover{opacity:.75}

.attach-list{display:flex;flex-direction:column;gap:6px;margin-bottom:8px}

.attach-item{display:flex;align-items:center;gap:9px;padding:8px 11px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface-2);font-size:var(--t-body)}

.attach-ic{color:var(--muted);flex-shrink:0;display:flex}

.attach-link{flex:1;min-width:0;color:var(--accent);text-decoration:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.attach-link:hover{text-decoration:underline}

.attach-item.file{gap:11px}

.attach-ic.file{color:var(--accent)}

.attach-thumb-wrap{flex-shrink:0;display:block;line-height:0}

.attach-thumb{width:40px;height:40px;object-fit:cover;border-radius:var(--r-sm);border:1px solid var(--line);display:block}

.attach-meta{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}

.attach-meta .attach-link{flex:none}

.attach-size{font-size:var(--t-xs);color:var(--faint);font-family:var(--mono)}

.attach-dl{color:var(--muted);flex-shrink:0;display:flex;padding:2px;border-radius:var(--r-xs);transition:var(--dur-fast)}

.attach-dl:hover{color:var(--accent);background:var(--accent-soft)}

.attach-actions{display:flex;gap:8px;flex-wrap:wrap}

/* ===== timeline interactions ===== */
.tl-ms.dragging{cursor:grabbing;filter:brightness(1.1)}
/* ==== components.044.css ==== */
/* ===== dashboard charts ===== */
.stat-card,.chart-card{position:relative}
/* ==== utilities.067.css ==== */
.chart-del{position:absolute;top:10px;right:10px;width:24px;height:24px;border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;color:var(--faint);opacity:0;transition:opacity var(--dur-fast);z-index:2;background:transparent}
/* ==== components.045.css ==== */
.stat-card:hover .chart-del,.chart-card:hover .chart-del{opacity:1}
/* ==== utilities.068.css ==== */
.chart-del:hover{background:var(--danger-soft);color:var(--danger)}

.add-chart{grid-column:span 12;display:flex;align-items:center;justify-content:center;gap:8px;padding:16px;border:1.5px dashed var(--line-3);border-radius:var(--r-lg);color:var(--muted);font-weight:600;font-size:var(--t-h3);cursor:pointer;background:transparent;transition:var(--dur-fast)}

.add-chart:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}

/* ===== calendar drag ===== */
.cal-ev{cursor:grab}

.cal-ev.dragging{opacity:.5}

.cal-cell.cal-drop{background:var(--accent-soft);box-shadow:inset 0 0 0 2px var(--accent)}

/* ===== board column collapse + reorder ===== */
.bc-head{cursor:grab}

.bc-caret{width:20px;height:20px;display:flex;align-items:center;justify-content:center;color:var(--faint);flex-shrink:0;transition:transform var(--dur-fast);border-radius:var(--r-xs)}

.bc-caret:hover{background:var(--surface-2);color:var(--ink-2)}
/* ==== features.025.css ==== */
.board-col.col-dragging{opacity:.55}

.board-col.col-drop{box-shadow:inset 0 0 0 2px var(--accent);border-radius:var(--r-lg)}

.board-col.collapsed{width:46px!important;min-width:46px!important;flex:0 0 46px!important}
/* ==== components.046.css ==== */
.board-col.collapsed .bc-body,.board-col.collapsed .bc-add,.board-col.collapsed .bc-dot,.board-col.collapsed .bc-menu{display:none}
/* ==== features.026.css ==== */
.board-col.collapsed .bc-head{flex-direction:column;gap:10px;height:auto;align-items:center;padding:10px 4px}

.board-col.collapsed .bc-caret{transform:rotate(-90deg)}

.board-col.collapsed .bc-title{writing-mode:vertical-rl;transform:rotate(180deg);white-space:nowrap;overflow:visible}
/* ==== utilities.069.css ==== */
/* ===== calendar week mode + more ===== */
.cal-more{cursor:pointer}

.cal-more:hover{color:var(--accent)}

.cal-more:focus-visible{outline:none;color:var(--accent);box-shadow:var(--ring);border-radius:var(--r-xs)}

.cal-modes{display:inline-flex;background:var(--well);border:1px solid var(--line-2);border-radius:var(--r-sm);padding:3px;gap:2px}

.cal-mode{padding:5px 12px;font-size:var(--t-sm);font-weight:600;color:var(--muted);border-radius:var(--r-xs);transition:var(--dur-instant)}

.cal-mode:hover{color:var(--ink)}

.cal-mode.active{background:var(--surface);color:var(--ink);box-shadow:var(--shadow-sm),inset 0 1px 0 var(--edge-hi)}
/* ==== layout.012.css ==== */
.cal-grid.week .cal-cell{min-height:440px}
/* ==== components.047.css ==== */
.recur-badge{color:var(--accent-700);background:var(--accent-soft)}
/* ==== utilities.070.css ==== */
/* Плашка состояния печати — в углу, не поверх всего интерфейса */
/* ============================================================
   ОДИН ЯЗЫК ДЛЯ СИСТЕМНЫХ СООБЩЕНИЙ (финальная полировка)
   Уведомление об итоге действия и индикатор долгой операции —
   это одна и та же роль: приложение отвечает человеку. Но
   выглядели они как из разных продуктов: тёмная таблетка внизу
   по центру против светлой карточки в правом нижнем углу, разные
   радиусы, разные шрифты. Теперь индикатор наследует облик
   уведомления и встаёт там же — просто чуть выше, чтобы, когда
   операция завершится, её итог появился ровно на том месте, куда
   человек уже смотрит, а не в противоположном углу экрана. */
.print-status{position:fixed;bottom:74px;left:50%;transform:translateX(-50%);z-index:50;display:flex;align-items:center;gap:10px;padding:12px 17px;background:var(--ink);color:var(--canvas);border-radius:var(--r-md);box-shadow:var(--shadow-lg);font-size:var(--t-body);font-weight:500;max-width:min(360px,calc(100vw - 24px))}

.print-status.err{background:var(--danger);color:var(--on-solid)}

.print-spin{width:13px;height:13px;border:2px solid rgba(255,255,255,.28);border-top-color:currentColor;border-radius:50%;animation:printSpin .7s linear infinite;flex-shrink:0}

@keyframes printSpin{to{transform:rotate(360deg)}}

.print-retry{margin-left:4px;padding:5px 11px;border:1px solid rgba(255,255,255,.35);border-radius:var(--r-sm);background:rgba(255,255,255,.14);color:inherit;font:inherit;font-size:var(--t-sm);font-weight:600;cursor:pointer;flex-shrink:0}

.print-retry:hover{background:rgba(255,255,255,.24)}

.print-retry:hover{background:var(--surface-3)}

@media print{.print-status{display:none!important}}

@media print{
  #sidebar,#topbar,#rail,.nav-scrim,.overlay,#panel,#toastRoot,#modalRoot,.tb-burger,.bulk-bar{display:none!important}
  #app{grid-template-columns:1fr!important;height:auto!important;display:block!important}
  .workspace{display:block!important}
  .content-scroll,#main{overflow:visible!important;height:auto!important}
  body{background:#fff!important}
  *{-webkit-print-color-adjust:exact!important;print-color-adjust:exact!important}
  .board-wrap{overflow:visible!important;flex-wrap:wrap!important}
  .board-col{break-inside:avoid}
  /* Найденная причина зависания предпросмотра печати на «Подготовка
     к предпросмотру»: content-visibility:auto (добавлен ранее для
     скорости отрисовки длинных списков) заставляет браузер пропускать
     раскладку невидимого сейчас контента. При обычной прокрутке это
     именно то, что нужно, но при печати браузеру требуется разложить
     ВСЁ содержимое сразу, чтобы разбить его на страницы, — и на
     большом списке задач Chrome остаётся в «Подготовке» неопределённо
     долго вместо того, чтобы сформировать документ. Для печати
     оптимизация отключается: скорость прокрутки здесь не важна, а
     полная, предсказуемая раскладка — обязательна. contain-intrinsic-size
     тоже сбрасывается, иначе элементы печатались бы с подставной,
     а не настоящей высотой. */
  .proj-item,.wl-row,.tl2-row,.task-row,.mini-task,.card{
    content-visibility:visible!important;
    contain-intrinsic-size:auto!important;
    contain:none!important;
  }
}

.wl-wrap{padding:14px var(--gutter) 40px;display:flex;flex-direction:column;gap:8px}

.wl-row{display:grid;grid-template-columns:230px 1fr;gap:22px;align-items:center;padding:14px 16px;border-radius:var(--r-lg);border:1px solid var(--line);background:var(--surface);box-shadow:var(--shadow-xs),inset 0 1px 0 var(--edge-hi);content-visibility:auto;contain-intrinsic-size:0 76px}

.wl-row.wl-over{border-color:var(--danger-line);background:var(--danger-soft)}

.wl-name{display:flex;align-items:center;gap:11px}

.wl-bar{display:flex;height:16px;border-radius:var(--r-sm);overflow:hidden;background:var(--well);box-shadow:inset 0 0 0 1px var(--line-2)}

.wl-bar>div{height:100%}

.bulk-bar{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);z-index:60;display:flex;align-items:center;gap:6px;background:var(--ink);color:var(--on-solid);padding:8px 10px;border-radius:var(--r-lg);box-shadow:var(--shadow-lg)}

[data-theme="dark"] .bulk-bar{background:var(--surface-3);border:1px solid var(--line-3);box-shadow:var(--shadow-lg),inset 0 1px 0 rgba(255,255,255,.06)}

.bulk-n{font-size:var(--t-body);font-weight:600;padding:0 8px 0 4px}
/* ==== components.048.css ==== */
.bulk-btn{display:inline-flex;align-items:center;gap:6px;font-size:var(--t-sm);font-weight:600;color:var(--on-solid);padding:7px 11px;border-radius:var(--r-sm);background:rgba(255,255,255,.14);transition:background var(--dur-instant)}

.bulk-btn:hover{background:rgba(255,255,255,.26)}

.bulk-btn.danger:hover{background:var(--danger)}
/* ==== features.027.css ==== */
/* Отметка выбора на карточке доски — тот же облик, что в списке:
   одинаковое действие должно выглядеть одинаково в обоих
   представлениях, иначе человек не узнаёт его. */
/* ============================================================
   ЕДИНАЯ ИНДИКАЦИЯ ПЕРЕТАСКИВАНИЯ
   На доске подсветка зоны была, в списке — нет: одно и то же
   действие в двух представлениях выглядело по-разному, и в списке
   человек не понимал, попадёт ли задача в этот раздел. Теперь у
   раздела списка та же мягкая подсветка, что у колонки доски.
   Курсор во время перетаскивания меняется по всему окну, чтобы
   было видно: жест идёт, а не «мышь залипла». */
.task-rows.dnd-over{background:var(--accent-soft);border-radius:var(--r-sm);
  outline:1px dashed var(--accent-line);outline-offset:-2px;transition:background var(--dur-instant)}
/* ==== base.006.css ==== */
body.dnd-active{cursor:grabbing}

body.dnd-active .task-row{cursor:grabbing}
/* ==== utilities.071.css ==== */
@media(prefers-reduced-motion:reduce){.task-rows.dnd-over{transition:none}}
/* ==== components.049.css ==== */
.card-sel{width:15px;height:15px;border-radius:var(--r-xs);border:1.5px solid var(--line-3);
  flex-shrink:0;opacity:0;transition:opacity var(--dur-instant),background var(--dur-instant),border-color var(--dur-instant);cursor:pointer}

.card:hover .card-sel,.card-sel.on{opacity:1}

.card-sel.on{background:var(--accent);border-color:var(--accent)}

.card-sel:hover{border-color:var(--accent)}
/* ==== utilities.072.css ==== */
@media(hover:none){.card-sel{opacity:1}}

.row-sel{width:16px;height:16px;border-radius:var(--r-xs);border:1.5px solid var(--line-3);flex-shrink:0;margin-right:2px;opacity:0;transition:opacity var(--dur-instant);cursor:pointer;background:var(--surface)}
/* ==== features.028.css ==== */
.task-row:hover .row-sel,.row-sel.on{opacity:1}
/* ==== utilities.073.css ==== */
.row-sel.on{background:var(--accent);border-color:var(--accent)}

.row-sel.on::after{content:'✓';color:var(--on-solid);font-size:var(--t-micro);display:flex;align-items:center;justify-content:center;height:100%;line-height:1}

.cf-mem{display:inline-flex;align-items:center;gap:5px;font-size:var(--t-sm);color:var(--ink-2)}
/* ==== components.050.css ==== */
.form-check{display:flex;align-items:center;gap:8px;padding:4px 0;font-size:var(--t-body);cursor:pointer}

/* accent-color — родное CSS-свойство для перекраски нативных чекбоксов
   и radio под цвет бренда, без замены их на самодельную разметку:
   меньше кода, встроенная поддержка hover/focus/disabled от самого
   браузера, и чекбокс наконец выглядит частью того же продукта, а не
   цветом операционной системы конкретного человека. Свойство —
   на input[type=checkbox/radio] глобально, а не только внутри
   .form-check: чекбоксы встречаются и вне формы (выбор проекта при
   приглашении, массовое перераспределение загруженности), у всех
   один и тот же цвет, без исключений по месту использования. */
input[type="checkbox"],input[type="radio"]{accent-color:var(--accent);cursor:pointer}

input[type="checkbox"]:disabled,input[type="radio"]:disabled{cursor:not-allowed;opacity:.5}

input[type="checkbox"]:focus-visible,input[type="radio"]:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

.form-check input{width:16px;height:16px}
/* ==== utilities.074.css ==== */
.act-item{display:flex;align-items:flex-start;gap:9px;padding:5px 0}

.act-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}

.act-txt{font-size:var(--t-sm);color:var(--ink-2);line-height:1.45}

.act-txt b{color:var(--ink);font-weight:600}

.act-time{font-size:var(--t-micro);color:var(--faint);font-family:var(--mono)}

.mention{color:var(--accent);font-weight:600;background:var(--accent-soft);padding:0 3px;border-radius:var(--r-xs)}

.comment-text .mention{white-space:nowrap}

.tb-sync{display:flex;align-items:center;gap:6px;font-size:var(--t-xs);font-family:var(--mono);letter-spacing:-.01em;color:var(--muted);padding:5px 10px;border-radius:var(--r-xl);border:1px solid var(--line);white-space:nowrap;cursor:pointer;user-select:none;transition:border-color var(--dur-fast),background var(--dur-fast)}

.tb-sync:hover{background:var(--surface-2);border-color:var(--line-2)}

.tb-sync:focus-visible{outline:none;box-shadow:var(--ring)}

.tb-sync-dot{width:7px;height:7px;border-radius:50%;background:var(--muted);flex:none}

.tb-sync.ok{color:var(--ok);border-color:var(--ok-soft)}

.tb-sync.ok .tb-sync-dot{background:var(--ok)}

.tb-sync.sync{color:var(--warn);border-color:var(--warn-soft)}

.tb-sync.sync .tb-sync-dot{background:var(--warn);animation:syncpulse 1s infinite}

.tb-sync.off{color:var(--muted)}

.tb-sync.off .tb-sync-dot{background:var(--muted)}

.tb-sync.err{color:var(--danger);border-color:var(--danger-soft)}

.tb-sync.err .tb-sync-dot{background:var(--danger)}

@keyframes syncpulse{0%,100%{opacity:1}50%{opacity:.3}}

@media(max-width:768px){.tb-sync{padding:5px 7px}.tb-sync-lbl{display:none}}

/* ============================================================
   ГЛАВНАЯ СТРАНИЦА КАК ЛЕНДИНГ (неавторизованный посетитель)
   Раздел «преобразование главной страницы в лендинг»: #authGate
   был фиксированным, центрированным на весь экран блоком — просто
   карточка входа, без единого слова о том, что это за продукт.
   Здесь тот же контейнер становится прокручиваемой страницей;
   сама карточка входа/регистрации не переписана ни в одной
   функции — showAuthGate()/doLogin()/doRegister() и все data-act
   остаются буквально теми же, только физически теперь находятся
   внутри hero-секции лендинга, а не одни на всём экране.
   Дизайн-система — те же переменные (--surface/--line/--r-lg и
   так далее), что и во всём остальном приложении, не новая. */
#authGate{position:fixed;inset:0;z-index:2000;background:var(--canvas);display:none;overflow-y:auto;padding:0}

/* ============================================================
   СОСТОЯНИЕ ЗАГРУЗКИ: КАБИНЕТ СКРЫТ, ПОКА АВТОРИЗАЦИЯ НЕ ОПРЕДЕЛЕНА
   ============================================================
   Разметка кабинета (#app и мобильная обвязка) находится в
   index.html и отрисовывается браузером сразу, ещё до того как
   выполнится frontend/main.js. Модуль отложен по спецификации
   (type="module"), а решение «кабинет или лендинг» принимается лишь
   после ответа ?action=me. Между первой отрисовкой и этим ответом
   посетитель видел пустой каркас кабинета, и только потом сверху
   ложился #authGate. Отсюда и мигание: чем медленнее сеть, тем
   дольше видно кабинет.

   Класс app-booting стоит прямо в теге <html>, то есть действует с
   самого первого кадра — не через скрипт, который тоже пришлось бы
   ждать. Снимается он в markAppReady(): это существующая функция,
   которая уже вызывается во ВСЕХ ветках bootAuth() — и когда
   показан лендинг, и когда открыт кабинет, и в ветке ошибки.
   Никаких таймеров и искусственных задержек здесь нет: показ
   привязан к факту завершения проверки, а не ко времени.

   visibility, а не display: смена display на #app задела бы
   раскладку (в utilities.070.css для печати стоит
   display:block!important) и обнулила бы измерения, на которые
   опирается render(). При visibility:hidden сетка остаётся на
   месте, элементы просто не рисуются, а фон страницы (body,
   var(--chrome)) остаётся тем же, что и был, — ни один цвет,
   отступ или шрифт не менялся.

   Мобильные .m-fab и .m-tabbar перечислены отдельно: они лежат
   рядом с #app, а не внутри него, и без этой строки на телефоне
   мелькали бы кнопка «Создать» и нижняя панель вкладок. */
html.app-booting #app,
html.app-booting .m-fab,
html.app-booting .m-tabbar{visibility:hidden}
/* ==== layout.013.css ==== */
.lp-header{position:sticky;top:0;z-index:10;display:flex;align-items:center;gap:20px;padding:16px clamp(20px,4vw,56px);background:var(--canvas);border-bottom:1px solid transparent;transition:border-color var(--dur),box-shadow var(--dur)}

.lp-header.scrolled{border-bottom-color:var(--line);box-shadow:var(--shadow-sm)}

.lp-header-brand{display:flex;align-items:center;gap:9px;font-size:var(--t-lg);font-weight:700;color:var(--ink);letter-spacing:-.03em;flex-shrink:0}

.lp-header-brand svg{color:var(--accent)}
.lp-brand-logo{width:20px;height:20px;object-fit:contain;border-radius:var(--r-sm);vertical-align:middle;flex-shrink:0}

.lp-nav{display:flex;align-items:center;gap:26px;margin-left:8px}

.lp-nav a{font-size:var(--t-h3);color:var(--ink-2);text-decoration:none;font-weight:500;transition:color var(--dur-fast)}

.lp-nav a:hover{color:var(--ink)}

.lp-header-right{display:flex;align-items:center;gap:10px;margin-left:auto}
/* ==== utilities.075.css ==== */
.lp-lang-sel{padding:7px 10px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface);color:var(--ink-2);font:inherit;font-size:var(--t-sm);cursor:pointer}

.lp-burger{display:none;width:38px;height:38px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface);align-items:center;justify-content:center;color:var(--ink);cursor:pointer;flex-shrink:0}
/* ==== layout.014.css ==== */
.lp-mobile-nav{display:none;flex-direction:column;gap:2px;padding:6px clamp(20px,4vw,56px) 14px;background:var(--canvas);border-bottom:1px solid var(--line)}

.lp-mobile-nav.show{display:flex}

.lp-mobile-nav a{padding:11px 4px;font-size:var(--t-h3);color:var(--ink-2);text-decoration:none;border-bottom:1px solid var(--line-2)}
/* ==== utilities.076.css ==== */
.lp-section{padding:clamp(52px,8vw,96px) clamp(20px,4vw,56px);max-width:1180px;margin:0 auto}

.lp-eyebrow{display:inline-flex;align-items:center;gap:7px;font-size:var(--t-sm);font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--accent-700);background:var(--accent-soft);padding:6px 12px;border-radius:var(--r-pill);margin-bottom:16px}

.lp-h2{font-size:clamp(24px,3.4vw,34px);font-weight:800;letter-spacing:-.03em;color:var(--ink);margin:0 0 10px}

.lp-lead{font-size:var(--t-h2);color:var(--muted);line-height:1.6;max-width:600px;margin:0 0 40px}

.lp-center{text-align:center;margin-left:auto;margin-right:auto}

.lp-hero{padding-top:clamp(40px,7vw,84px);display:grid;grid-template-columns:1.1fr .9fr;gap:56px;align-items:center}

.lp-hero-title{font-size:clamp(32px,5vw,52px);font-weight:800;letter-spacing:-.035em;line-height:1.08;color:var(--ink);margin:0 0 18px}

.lp-hero-title .accent{color:var(--accent)}

.lp-hero-desc{font-size:var(--t-h2);line-height:1.6;color:var(--muted);max-width:480px;margin:0 0 28px}

.lp-hero-ctas{display:flex;gap:12px;flex-wrap:wrap;margin-bottom:36px}
/* ==== components.051.css ==== */
.lp-btn-lg{padding:14px 26px;font-size:var(--t-h3);border-radius:var(--r-md)}
/* ==== utilities.077.css ==== */
.lp-hero-authwrap{display:flex;justify-content:center}

.lp-hero-mock{margin-top:20px;border:1px solid var(--line);border-radius:var(--r-xl);background:var(--surface);box-shadow:var(--shadow-lg);overflow:hidden}

.lp-hero-mock-bar{display:flex;gap:6px;padding:11px 14px;border-bottom:1px solid var(--line-2);background:var(--surface-2)}

.lp-hero-mock-dot{width:9px;height:9px;border-radius:50%;background:var(--line-2)}

.lp-hero-mock-body{padding:16px}

.lp-mock-row{display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:var(--r-sm);margin-bottom:6px}

.lp-mock-row.done{opacity:.55}

.lp-mock-check{width:16px;height:16px;border-radius:var(--r-xs);border:1.6px solid var(--line-2);flex-shrink:0}

.lp-mock-check.on{background:var(--ok);border-color:var(--ok);position:relative}

.lp-mock-name{flex:1;height:9px;border-radius:var(--r-xs);background:var(--line-2)}

.lp-mock-tag{width:52px;height:18px;border-radius:var(--r-pill);flex-shrink:0}
/* ==== layout.015.css ==== */
.lp-features-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
/* ==== components.052.css ==== */
.lp-feature-card{padding:26px 22px;border:1px solid var(--line);border-radius:var(--r-lg);background:var(--surface);transition:transform var(--dur-fast),box-shadow var(--dur-fast),border-color var(--dur-fast)}

.lp-feature-card:hover{transform:translateY(-2px);box-shadow:var(--shadow-md);border-color:var(--line-2)}
/* ==== utilities.078.css ==== */
.lp-feature-ic{width:42px;height:42px;border-radius:var(--r-md);background:var(--accent-soft);color:var(--accent-700);display:flex;align-items:center;justify-content:center;margin-bottom:14px}

.lp-feature-title{font-size:var(--t-h2);font-weight:700;color:var(--ink);margin-bottom:6px}

.lp-feature-desc{font-size:var(--t-body);color:var(--muted);line-height:1.55}

.lp-steps{display:grid;grid-template-columns:repeat(4,1fr);gap:20px}

.lp-step{position:relative;padding:24px 20px 20px}

.lp-step-num{width:34px;height:34px;border-radius:50%;background:var(--ink);color:var(--canvas);display:flex;align-items:center;justify-content:center;font-weight:700;font-size:var(--t-h3);margin-bottom:14px}

.lp-step-title{font-size:var(--t-h3);font-weight:700;color:var(--ink);margin-bottom:6px}

.lp-step-desc{font-size:var(--t-body);color:var(--muted);line-height:1.55}
/* ==== layout.016.css ==== */
.lp-showcase-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:18px}
/* ==== components.053.css ==== */
.lp-showcase-card{display:flex;gap:16px;padding:22px;border:1px solid var(--line);border-radius:var(--r-lg);background:var(--surface)}
/* ==== utilities.079.css ==== */
.lp-showcase-ic{width:40px;height:40px;border-radius:var(--r-md);background:var(--info-soft);color:var(--info);display:flex;align-items:center;justify-content:center;flex-shrink:0}

.lp-showcase-title{font-size:var(--t-h3);font-weight:700;color:var(--ink);margin-bottom:5px}

.lp-showcase-desc{font-size:var(--t-body);color:var(--muted);line-height:1.55}
/* ==== layout.017.css ==== */
.lp-proof-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:18px;text-align:center}
/* ==== components.054.css ==== */
.lp-proof-card{padding:22px 14px;border:1px solid var(--line);border-radius:var(--r-lg);background:var(--surface)}
/* ==== utilities.080.css ==== */
.lp-proof-ic{color:var(--accent);margin-bottom:10px}

.lp-proof-title{font-size:var(--t-h3);font-weight:700;color:var(--ink);margin-bottom:4px}

.lp-proof-desc{font-size:var(--t-sm);color:var(--muted);line-height:1.5}

.lp-faq-list{max-width:720px;margin:0 auto}

.lp-faq-item{border-bottom:1px solid var(--line)}

.lp-faq-q{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:18px 4px;cursor:pointer;font-size:var(--t-h3);font-weight:600;color:var(--ink)}

.lp-faq-q:hover{color:var(--accent)}

.lp-faq-q:focus-visible{outline:none;color:var(--accent);box-shadow:var(--ring);border-radius:var(--r-xs)}

.lp-faq-q .car{color:var(--faint);transition:transform var(--dur);flex-shrink:0}

.lp-faq-item.open .lp-faq-q .car{transform:rotate(180deg)}

/* --- Раскрытие ответа: раньше — max-height:200px по фиксированному
   числу пикселей. Работало, пока ответы короткие, но было хрупким по
   конструкции — любой более длинный ответ (или просто более
   многословный перевод на другой язык) обрезался бы без предупреждения,
   overflow:hidden прятал бы остаток текста без какой-либо возможности
   его увидеть. grid-template-rows: 0fr → 1fr — тот же плавный переход
   визуально, но по-настоящему подстраивается под фактическую высоту
   содержимого, какой бы она ни была, а не под угаданное число. */
.lp-faq-a{display:grid;grid-template-rows:0fr;transition:grid-template-rows var(--dur) ease}

.lp-faq-item.open .lp-faq-a{grid-template-rows:1fr}

.lp-faq-a-inner{min-height:0;overflow:hidden;padding:0 4px 18px;font-size:var(--t-body);color:var(--muted);line-height:1.6}

.lp-final-cta{text-align:center;background:var(--surface-2);border-radius:var(--r-xl);padding:clamp(40px,6vw,64px) clamp(20px,4vw,40px);border:1px solid var(--line)}
/* ==== layout.018.css ==== */
.lp-footer{border-top:1px solid var(--line);padding:36px clamp(20px,4vw,56px) 28px}

.lp-footer-inner{max-width:1180px;margin:0 auto;display:flex;justify-content:space-between;gap:30px;flex-wrap:wrap}

.lp-footer-brand{display:flex;align-items:center;gap:8px;font-size:var(--t-h3);font-weight:700;color:var(--ink);margin-bottom:8px}

.lp-footer-desc{font-size:var(--t-sm);color:var(--faint);max-width:280px;line-height:1.5}

.lp-footer-col-title{font-size:var(--t-sm);font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--faint);margin-bottom:12px}

.lp-footer-links{display:flex;flex-direction:column;gap:9px}

.lp-footer-links a{font-size:var(--t-body);color:var(--ink-2);text-decoration:none}

.lp-footer-links a:hover{color:var(--ink)}

.lp-footer-bottom{max-width:1180px;margin:24px auto 0;padding-top:20px;border-top:1px solid var(--line-2);font-size:var(--t-sm);color:var(--faint)}
/* ==== utilities.081.css ==== */
/* По умолчанию копия языка в меню скрыта: на широких экранах
   переключатель стоит в шапке. */
.lp-mnav-lang{display:none;padding:10px 0 2px}

@media (max-width:860px){
  .lp-nav{display:none}
  /* 44px вместо 38: это единственная кнопка, открывающая навигацию
     лендинга на телефоне, и она была меньше рекомендованной зоны
     нажатия. Рамка и вид не меняются — только размер площадки. */
  .lp-burger{display:flex;width:44px;height:44px}
  .lp-hero{grid-template-columns:1fr}
  .lp-hero-authwrap{order:-1}
  .lp-features-grid{grid-template-columns:1fr 1fr}
  .lp-steps{grid-template-columns:1fr 1fr}
  .lp-showcase-grid{grid-template-columns:1fr}
  .lp-proof-grid{grid-template-columns:1fr 1fr}
}

@media (max-width:520px){
  .lp-features-grid{grid-template-columns:1fr}
  .lp-steps{grid-template-columns:1fr}
  .lp-proof-grid{grid-template-columns:1fr 1fr}
  .lp-header-right .lp-lang-sel{display:none}
  /* Копия переключателя внутри меню-гамбургера. Шапочная в этой
     ширине скрыта строкой выше, и без этой пары сменить язык на
     телефоне было нельзя ни одним способом. Показываются они всегда
     по очереди, никогда вместе. */
  .lp-mnav-lang{display:block}
  .lp-mnav-lang .lp-lang-sel{display:block;width:100%}
}

.auth-wrap{width:100%;max-width:380px}
/* ==== components.055.css ==== */
.auth-card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-xl);padding:32px 28px;box-shadow:var(--shadow-lg),inset 0 1px 0 var(--edge-hi);display:flex;flex-direction:column;gap:11px}
/* ==== utilities.082.css ==== */
.auth-brand{display:flex;align-items:center;gap:10px;font-size:var(--t-h1);font-weight:700;color:var(--ink);letter-spacing:-.035em}

.auth-brand svg{color:var(--accent)}

.auth-sub{font-size:var(--t-body);color:var(--muted);margin-bottom:6px}
/* ==== components.056.css ==== */
.auth-tabs{display:flex;gap:4px;background:var(--well);border:1px solid var(--line-2);border-radius:var(--r-md);padding:4px;margin-bottom:4px}

.auth-tab{flex:1;padding:8px;border:0;background:transparent;border-radius:var(--r-sm);font:inherit;font-size:var(--t-body);font-weight:600;color:var(--muted);cursor:pointer;transition:var(--dur-fast)}

.auth-tab.on{background:var(--surface);color:var(--ink);box-shadow:var(--shadow-sm),inset 0 1px 0 var(--edge-hi)}
/* ==== utilities.083.css ==== */
.auth-in{height:38px;padding:0 12px;border:1px solid var(--line);border-radius:var(--r-sm);font:inherit;font-size:var(--t-h3);background:var(--surface-2);color:var(--ink);outline:none;transition:var(--dur-fast)}

.auth-in:focus{border-color:var(--accent);background:var(--surface);box-shadow:var(--ring)}

/* --- Показать/скрыть пароль: кнопка-глаз внутри самого поля, справа.
   Обёртка нужна только для позиционирования — сам .auth-in внутри
   остаётся тем же элементом со всеми своими состояниями (focus/err),
   просто с запасом места под текст справа, чтобы длинный пароль не
   заезжал под кнопку. */
.auth-pwd-wrap{position:relative}

.auth-pwd-wrap .auth-in{width:100%;padding-right:40px}
/* ==== components.057.css ==== */
.auth-pwd-toggle{
  position:absolute;top:50%;right:4px;transform:translateY(-50%);
  width:30px;height:30px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;
  color:var(--faint);transition:var(--dur-instant);
}

.auth-pwd-toggle:hover{background:var(--surface-3);color:var(--ink)}

.auth-pwd-toggle:focus-visible{outline:none;box-shadow:var(--ring)}

/* --- Состояние ошибки — единое для всех текстовых полей формы, не
   только auth-in: тот же красный контур на .form-input/.field-input,
   если где-то ещё понадобится пометить поле как невалидное. Раньше
   такого состояния не существовало вовсе — ошибка формы показывалась
   только отдельной строкой текста, само поле никак не подсвечивалось. */
.auth-in.err,.form-input.err,.field-input.err{border-color:var(--danger-line);background:var(--danger-soft)}

.auth-in.err:focus,.form-input.err:focus,.field-input.err:focus{border-color:var(--danger);box-shadow:0 0 0 3px var(--danger-soft)}

.auth-btn{margin-top:6px;height:var(--ctl-h-lg);padding:0 12px;font-size:var(--t-h3);font-weight:600;justify-content:center;width:100%}

/* --- Индикатор отправки: та же анимация @keyframes spin, что уже
   используется для остальных спиннеров в приложении, не новая. Сам
   :disabled уже приглушается общим .btn:disabled — здесь только
   добавляется вращающийся кружок перед текстом «Загрузка…». */
.auth-btn-spinner{
  display:inline-block;width:15px;height:15px;margin-right:8px;vertical-align:-3px;
  border:2px solid rgba(255,255,255,.4);border-top-color:#fff;border-radius:50%;
  animation:spin .7s linear infinite;
}
/* ==== utilities.084.css ==== */
.auth-err{font-size:var(--t-sm);color:var(--danger);min-height:15px;line-height:1.3}

.auth-invite{display:flex;align-items:center;gap:8px;font-size:var(--t-sm);color:var(--accent-700);background:var(--accent-soft);border:1px solid var(--accent-soft-2);border-radius:var(--r-ctl);padding:9px 11px;line-height:1.35}

.auth-invite svg{flex:none;color:var(--accent)}

.auth-legal{font-size:var(--t-xs);color:var(--faint);text-align:center;margin-top:4px;line-height:1.55}

.auth-legal a{color:var(--muted);text-decoration:underline;cursor:pointer}

.verify-bar{position:fixed;left:50%;transform:translateX(-50%);bottom:18px;z-index:50;display:flex;align-items:center;gap:10px;background:var(--surface);border:1px solid var(--warn-soft);border-left:3px solid var(--warn);box-shadow:var(--shadow-lg);border-radius:var(--r-md);padding:9px 12px;font-size:var(--t-sm);color:var(--ink-2);max-width:min(560px,92vw)}

.verify-bar svg{color:var(--warn);flex:none}

.verify-x{background:transparent;border:0;color:var(--faint);cursor:pointer;padding:2px;display:flex}

.guest-bar{position:fixed;left:50%;transform:translateX(-50%);top:10px;z-index:50;display:flex;align-items:center;gap:7px;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-pill);padding:5px 13px;font-size:var(--t-xs);color:var(--muted);box-shadow:var(--shadow-md)}

.guest-bar svg{color:var(--muted)}

.tm-sel{width:auto;padding:5px 8px;font-size:var(--t-sm)}

.tm-role{font-size:var(--t-sm);color:var(--muted);padding:0 6px}

.tm-you{font-size:var(--t-micro);color:var(--accent);font-weight:600}
/* ==== components.058.css ==== */
.tm-badge{font-size:var(--t-micro);color:var(--danger);background:var(--danger-soft);padding:1px 6px;border-radius:var(--r-pill);font-weight:600}
/* ==== utilities.085.css ==== */
.trash-list{display:flex;flex-direction:column;border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden;background:var(--surface);box-shadow:var(--shadow-xs)}

.trash-row{display:flex;align-items:center;gap:11px;padding:11px 14px;border-bottom:1px solid var(--line)}

.trash-row:last-child{border-bottom:0}

.trash-ic{width:30px;height:30px;border-radius:var(--r-sm);background:var(--canvas);display:flex;align-items:center;justify-content:center;color:var(--muted);flex:none}

.trash-main{flex:1;min-width:0}

.trash-name{font-size:var(--t-body);color:var(--ink);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.trash-sub{font-size:var(--t-xs);color:var(--faint);margin-top:2px}

.ntf-row{display:flex;align-items:flex-start;gap:10px;padding:9px 0;cursor:pointer}
/* ==== components.059.css ==== */
.ntf-row input{width:16px;height:16px;margin-top:1px;flex:none}
/* ==== utilities.086.css ==== */
.ntf-t{display:block;font-size:var(--t-body);color:var(--ink);font-weight:500}

.ntf-s{display:block;font-size:var(--t-xs);color:var(--faint);margin-top:1px;line-height:1.4}

.ntf-main{border-bottom:1px solid var(--line);padding-bottom:12px;margin-bottom:4px}

.ntf-group{padding-left:2px}

.ntf-dim{opacity:.45}

.mh-wrap{display:flex;flex-direction:column;gap:4px;align-items:flex-start}

.mh-home{font-size:var(--t-micro);color:var(--faint);background:var(--canvas);padding:1px 5px;border-radius:var(--r-xs);margin-left:6px;font-family:var(--mono)}

.mh-item{display:flex;align-items:center;gap:2px;width:100%}
/* ==== components.060.css ==== */
.mh-item .field-btn{flex:1;min-width:0}
/* ==== utilities.087.css ==== */
.mh-x{background:transparent;border:0;color:var(--faint);cursor:pointer;padding:3px;display:flex;border-radius:var(--r-xs)}

.mh-x:hover{background:var(--danger-soft);color:var(--danger)}

.mh-add{background:transparent;border:1px dashed var(--line-2);color:var(--muted);cursor:pointer;font:inherit;font-size:var(--t-xs);padding:4px 9px;border-radius:var(--r-sm);display:flex;align-items:center;gap:4px;margin-top:2px}

.mh-add:hover{border-color:var(--accent);color:var(--accent)}

.row-caret{width:16px;height:16px;display:flex;align-items:center;justify-content:center;color:var(--faint);cursor:pointer;border-radius:var(--r-xs);flex:none}

.row-caret svg{transform:rotate(-90deg);transition:transform var(--dur-instant)}

.row-caret.open svg{transform:rotate(0)}

.row-caret.ph{opacity:0}
/* ==== features.029.css ==== */
.task-row:hover .row-caret.ph{opacity:.6}
/* ==== utilities.088.css ==== */
.row-caret:hover{background:var(--surface-2);color:var(--ink)}

.sub-indent{width:34px;flex:none}
/* ==== features.030.css ==== */
.sub-row .task-name{color:var(--ink-2)}

.sub-row.done .task-name{color:var(--faint);text-decoration:line-through}

.sub-row .task-check.sub-done{background:var(--ok);border-color:var(--ok);color:var(--on-solid)}
/* ==== utilities.089.css ==== */
.srow-add:hover{background:transparent}

.add-sub-inline{border:0;background:transparent;outline:0;color:var(--ink);font:inherit;font-size:var(--t-body);width:100%;padding:2px 0}

.add-sub-inline::placeholder{color:var(--faint)}

.cell-click{cursor:pointer}

/* --- Кнопка меню в строке задачи ------------------------------
   В покое невидима, но место под неё зарезервировано: если бы
   кнопка появлялась и раздвигала колонки, вся строка дёргалась бы
   при каждом наведении мыши. */
.row-more{width:28px;display:flex;justify-content:flex-end;align-items:center}
/* ==== components.061.css ==== */
.row-more-btn{width:26px;height:26px;display:flex;align-items:center;justify-content:center;
  border-radius:var(--r-xs);color:var(--faint);opacity:0;transition:opacity var(--dur-instant),background var(--dur-instant)}

.task-row:hover .row-more-btn,.row-more-btn:focus-visible{opacity:1}

.row-more-btn:hover{background:var(--surface-3);color:var(--ink-2)}

.row-more-btn:focus-visible{outline:none;box-shadow:var(--ring)}
/* ==== utilities.090.css ==== */
/* Группа тегов кликается целиком — нажимать в 8-пиксельный зазор
   между отдельными тегами было бы издевательством. */
.tag-wrap{display:inline-flex;gap:4px;align-items:center;flex-wrap:nowrap;min-width:0}

.tag-more{opacity:.7}

@media(hover:none){.row-more-btn{opacity:1}}

.due-pill[data-act]{cursor:pointer}
/* ==== components.062.css ==== */
.cm-tabs{display:flex;align-items:center;gap:16px;border-bottom:1px solid var(--line);margin:2px 0 10px}

.cm-tab{font-size:var(--t-body);font-weight:600;color:var(--muted);padding:4px 0 8px;border-bottom:2px solid transparent;cursor:pointer;display:flex;align-items:center;gap:6px}

.cm-tab.active{color:var(--ink);border-bottom-color:var(--ink)}
/* ==== utilities.091.css ==== */
.cm-sort{margin-left:auto;font-size:var(--t-xs);color:var(--faint);cursor:pointer;display:flex;align-items:center;gap:4px;padding-bottom:6px}

.cm-sort:hover{color:var(--ink)}

.desc-tools{display:flex;gap:4px;margin-top:6px}

.desc-tools .dt{width:28px;height:26px;display:flex;align-items:center;justify-content:center;background:transparent;border:1px solid var(--line-2);border-radius:var(--r-xs);color:var(--muted);cursor:pointer;font:inherit;font-size:var(--t-xs)}

.desc-tools .dt:hover{background:var(--surface-2);color:var(--ink)}

.rich-h1{font-size:var(--t-lg);font-weight:700;color:var(--ink);margin:10px 0 6px}

.rich-h2{font-size:var(--t-h3);font-weight:700;color:var(--ink);margin:14px 0 5px}

.rich-h3{font-size:var(--t-body);font-weight:700;color:var(--ink);margin:11px 0 4px}

.rich-hr{border:0;border-top:1px solid var(--line);margin:12px 0}

.rich-code{background:var(--canvas);border:1px solid var(--line);border-radius:var(--r-sm);padding:10px 12px;font-family:var(--mono);font-size:var(--t-sm);line-height:1.55;white-space:pre-wrap;margin:6px 0;overflow-x:auto}

.ms-ic{color:var(--warn);font-size:var(--t-body);width:16px;text-align:center}
/* ==== components.063.css ==== */
.menu-kbd{margin-left:auto;font-size:var(--t-micro);color:var(--faint);font-family:var(--mono)}
/* ==== utilities.092.css ==== */
.chip-caret{padding:0 7px}

.rich-img{max-width:100%;max-height:420px;border-radius:var(--r-sm);margin:6px 0;display:block;border:1px solid var(--line)}

.prof-head{display:flex;gap:20px;align-items:center;padding:8px var(--gutter) 18px;margin:0 calc(-1 * var(--gutter))}

.prof-ava{width:92px;height:92px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:32px;font-weight:700;color:var(--on-solid);flex:none}

/* min-width:0 — без него длинный email в .prof-sub (обычно без
   пробелов, значит браузеру негде перенести строку) не давал бы
   flex-элементу сжаться теснее собственного содержимого и раздвигал
   бы шапку профиля вбок на узких экранах. Сама причина та же, что уже
   не раз чинилась в этой серии правок (усечение/перенос текста внутри
   flex) — только здесь нужен перенос, а не многоточие, поэтому решение
   другое: overflow-wrap вместо ellipsis. */
.prof-hmain{min-width:0}

.prof-name{font-size:26px;font-weight:700;letter-spacing:-.035em;color:var(--ink);overflow-wrap:anywhere}

.prof-sub{font-size:var(--t-body);color:var(--muted);margin-top:3px;overflow-wrap:anywhere}

.prof-chips{display:flex;gap:8px;margin-top:10px;flex-wrap:wrap}

.prof-chip{display:flex;align-items:center;gap:6px;font-size:var(--t-sm);color:var(--ink-2);background:var(--surface);border:1px solid var(--line);border-radius:var(--r-xl);padding:5px 12px;box-shadow:var(--shadow-xs)}
/* ==== layout.019.css ==== */
.prof-grid{display:grid;grid-template-columns:340px 1fr;gap:16px;align-items:start;padding:0 var(--gutter);margin:0 calc(-1 * var(--gutter))}
/* ==== components.064.css ==== */
.prof-card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);padding:20px;box-shadow:var(--shadow-sm),inset 0 1px 0 var(--edge-hi)}

.prof-card-title{font-size:var(--t-xs);font-weight:600;color:var(--faint);margin-bottom:14px}
/* ==== utilities.093.css ==== */
.prof-fld{margin-bottom:12px}

.prof-lbl{font-size:var(--t-xs);color:var(--faint);margin-bottom:4px;font-weight:600}

.prof-val{font-size:var(--t-body);color:var(--ink-2);line-height:1.5}

@media(max-width:900px){.prof-grid{grid-template-columns:1fr}}
/* ==== components.065.css ==== */
.people-cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:12px}

.person-card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);padding:20px 15px;display:flex;flex-direction:column;align-items:center;text-align:center;cursor:pointer;box-shadow:var(--shadow-xs),inset 0 1px 0 var(--edge-hi);transition:var(--dur-fast)}

.person-card:hover{border-color:var(--line-3);transform:translateY(-2px);box-shadow:var(--shadow),inset 0 1px 0 var(--edge-hi)}
/* ==== utilities.094.css ==== */
.pc-ava{width:64px;height:64px;font-size:var(--t-h1);margin-bottom:10px}

.pc-name{font-size:var(--t-h3);font-weight:700;color:var(--ink)}
/* ==== components.066.css ==== */
.pc-former{font-size:var(--t-micro);color:var(--danger);background:var(--danger-soft);padding:1px 6px;border-radius:var(--r-pill)}
/* ==== utilities.095.css ==== */
.pc-sub{font-size:var(--t-sm);color:var(--muted);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}

.pc-stats{font-size:var(--t-xs);color:var(--faint);margin-top:8px;display:flex;align-items:center;gap:5px}

.hdr-stu{display:inline-flex;align-items:center;gap:6px;font-size:var(--t-xs);font-weight:600;border-radius:var(--r-pill);padding:4px 10px;margin-left:10px;cursor:pointer;vertical-align:middle}

.hdr-stu-empty{color:var(--muted);border:1px dashed var(--line-3)}

.hdr-stu-empty:hover{color:var(--ink);border-color:var(--ink)}

.hdr-stu:focus-visible{outline:none;box-shadow:var(--ring)}

.pm-wrap{max-width:760px}

.pm-composer{margin-bottom:18px}

.pm-item{display:flex;gap:10px;padding:12px 0;border-bottom:1px solid var(--line)}

.pm-body{flex:1;min-width:0}
/* ==== layout.020.css ==== */
.files-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:12px}
/* ==== components.067.css ==== */
.file-card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden;box-shadow:var(--shadow-xs),inset 0 1px 0 var(--edge-hi);transition:var(--dur-fast)}

.file-card:hover{border-color:var(--line-3);box-shadow:var(--shadow)}
/* ==== utilities.096.css ==== */
.fc-prev{display:flex;align-items:center;justify-content:center;height:112px;background:var(--well);text-decoration:none;border-bottom:1px solid var(--line-2)}

.fc-prev img{width:100%;height:100%;object-fit:cover}

.fc-ic{color:var(--faint)}

.fc-name{font-size:var(--t-sm);font-weight:600;color:var(--ink);padding:8px 10px 2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.fc-sub{font-size:var(--t-xs);color:var(--faint);padding:0 10px 9px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* ==== features.031.css ==== */
.fc-task{color:var(--muted);cursor:pointer}

.fc-task:hover{color:var(--accent);text-decoration:underline}
/* ==== utilities.097.css ==== */
.tag-row{display:flex;flex-wrap:wrap;gap:5px;align-items:center}

.tag-chip{display:inline-flex;align-items:center;gap:4px;font-size:var(--t-xs);font-weight:600;border-radius:var(--r-md);padding:3px 9px}

.tag-x{display:inline-flex;cursor:pointer;opacity:.6}

.tag-x:hover{opacity:1}

.tag-mini{display:inline-flex;font-size:var(--t-micro);font-weight:700;border-radius:var(--r-sm);padding:1px 7px;margin-left:6px;flex:none}
/* ==== components.068.css ==== */
.appr-badge{display:inline-flex;font-size:var(--t-micro);font-weight:700;border-radius:var(--r-sm);padding:1px 7px;margin-left:6px;flex:none;background:var(--warn-soft);color:var(--warn-strong)}

.appr-badge.approved{background:var(--ok-soft);color:var(--ok-strong)}

.appr-badge.rejected{background:var(--danger-soft);color:var(--danger-strong)}

.appr-badge.changes{background:var(--info-soft);color:var(--info-strong)}
/* ==== utilities.098.css ==== */
.appr-block{margin:12px 0 4px;padding:14px;border:1px solid var(--line);border-radius:var(--r-md);background:var(--surface-2)}

.appr-cur{font-size:var(--t-sm);font-weight:700;margin-bottom:9px;color:var(--warn-strong)}

.appr-cur.approved{color:var(--ok-strong)}

.appr-cur.rejected{color:var(--danger-strong)}

.appr-cur.changes{color:var(--info-strong)}
/* ==== components.069.css ==== */
.appr-btns{display:flex;gap:7px;flex-wrap:wrap}
/* ==== utilities.099.css ==== */
.pp-pop{width:320px;padding:10px;max-height:none}

.pp-head{font-size:var(--t-xs);font-weight:600;color:var(--faint);display:flex;align-items:center;gap:8px;padding:2px 2px 8px}

.pp-leave{margin-left:auto;font-size:var(--t-micro);font-weight:600;color:var(--muted);cursor:pointer;text-transform:none;letter-spacing:0;display:flex;align-items:center;gap:4px}

.pp-leave:hover{color:var(--accent)}

.pp-box{display:flex;flex-wrap:wrap;gap:5px;align-items:center;border:1.6px solid var(--accent);border-radius:var(--r-sm);padding:6px 7px;background:var(--surface-2)}

.pp-box-sm{border-color:var(--line);margin:0 2px 6px}

.pp-chip{display:inline-flex;align-items:center;gap:5px;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-pill);padding:2px 7px 2px 3px;font-size:var(--t-sm);color:var(--ink)}

.pp-nm{max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.pp-x{display:inline-flex;cursor:pointer;color:var(--faint)}

.pp-x:hover{color:var(--danger)}
/* ==== components.070.css ==== */
.pp-input{flex:1;min-width:110px;border:0;background:transparent;outline:0;color:var(--ink);font:inherit;font-size:var(--t-body);padding:2px 0}

.pp-input::placeholder{color:var(--faint)}

.asg-input{flex:1;min-width:110px;border:0;background:transparent;outline:0;color:var(--ink);font:inherit;font-size:var(--t-body);padding:2px 0}

.asg-input::placeholder{color:var(--faint)}
/* ==== utilities.100.css ==== */
.pp-list{margin-top:6px;max-height:230px;overflow-y:auto}

.pp-sug{display:flex;align-items:center;gap:8px;padding:7px 8px;border-radius:var(--r-sm);cursor:pointer;font-size:var(--t-body);color:var(--ink)}

.pp-sug:hover{background:var(--surface-2)}

.pp-sug-nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.pp-sug-role{margin-left:auto;font-size:var(--t-xs);color:var(--faint);flex:none}

.pp-new{color:var(--accent);font-weight:600}

.pp-dim{opacity:.5;cursor:default}

.pp-guest{font-size:var(--t-micro);font-weight:700;color:var(--warn-strong);background:var(--warn-soft);padding:1px 5px;border-radius:var(--r-pill);flex:none}

.pp-chip-guest{border-color:var(--warn)}

.acc-guest{display:flex;align-items:center;gap:8px;padding:5px 0;font-size:var(--t-body);color:var(--ink-2)}
/* ==== components.071.css ==== */
.acc-guest button{margin-left:auto}
/* ==== utilities.101.css ==== */
.pp-dim:hover{background:transparent}

.pp-none{font-size:var(--t-sm);color:var(--faint);padding:8px}

.pp-foot{border-top:1px solid var(--line);margin-top:7px;padding-top:7px;font-size:var(--t-xs);color:var(--faint)}

.pp-link{display:inline-flex;align-items:center;gap:5px;color:var(--accent);cursor:pointer;font-weight:600}

.dg-status{display:flex;align-items:center;gap:12px;padding:13px 15px;border-radius:var(--r-md);border:1px solid var(--line);background:var(--surface);margin-bottom:12px;box-shadow:var(--shadow-xs)}

.dg-status.ok{border-left:3px solid var(--ok)}

.dg-status.warn{border-left:3px solid var(--warn)}

.dg-status.bad{border-left:3px solid var(--danger)}

.dg-big{width:12px;height:12px;border-radius:50%;background:var(--faint);flex:none}

.dg-status.ok .dg-big{background:var(--ok)}

.dg-status.warn .dg-big{background:var(--warn)}

.dg-status.bad .dg-big{background:var(--danger)}

.dg-st-lbl{font-size:var(--t-h3);font-weight:700;color:var(--ink)}

.dg-st-sub{font-size:var(--t-xs);color:var(--faint);margin-top:2px}

.dg-alert{border-radius:var(--r-sm);padding:9px 12px;font-size:var(--t-sm);line-height:1.6;margin-bottom:10px}

.dg-alert.bad{background:var(--danger-soft);color:var(--danger)}

.dg-alert.warn{background:var(--warn-soft);color:var(--warn)}

.dg-alert div{display:flex;align-items:center;gap:7px}

.dg-row{display:flex;align-items:center;gap:8px;padding:5px 0;font-size:var(--t-sm)}

.dg-lbl{color:var(--muted)}

.dg-val{margin-left:auto;color:var(--ink-2);font-weight:600;text-align:right}

.dg-dot{width:7px;height:7px;border-radius:50%;background:var(--faint);flex:none}

.dg-dot.ok{background:var(--ok)}

.dg-dot.warn{background:var(--warn)}

.dg-dot.bad{background:var(--danger)}

.dg-mono{font-family:var(--mono);font-size:var(--t-xs);color:var(--ink-2);word-break:break-all}

.dg-log{background:var(--canvas);border:1px solid var(--line);border-radius:var(--r-sm);padding:9px 11px;font-family:var(--mono);font-size:var(--t-micro);line-height:1.5;max-height:170px;overflow:auto;white-space:pre-wrap;margin:8px 0 0}

.dg-cands{margin-top:5px}

.dg-cand{display:flex;align-items:center;gap:7px;padding:3px 0;font-size:var(--t-xs)}

.dg-cand .dg-val{font-size:var(--t-micro);font-weight:400;color:var(--faint)}

.qr-svg{display:block;border-radius:var(--r-sm);background:#fff;padding:8px}

.tf-steps{display:flex;flex-direction:column;gap:16px}

.tf-step{display:flex;gap:11px;align-items:flex-start}

.tf-num{width:22px;height:22px;border-radius:50%;background:var(--accent);color:var(--on-solid);font-size:var(--t-sm);font-weight:700;display:flex;align-items:center;justify-content:center;flex:none;margin-top:1px}

.tf-st{font-size:var(--t-body);font-weight:600;color:var(--ink);margin-bottom:7px}

.tf-qr{display:inline-block}

.tf-code{font-family:var(--mono);font-size:var(--t-lg);letter-spacing:5px;text-align:center;max-width:190px}

.tf-err{font-size:var(--t-sm);color:var(--danger);margin-top:5px;min-height:15px}

.tf-on{display:flex;align-items:center;gap:11px;padding:12px 14px;border-radius:var(--r-md);background:var(--ok-soft);margin-bottom:12px}

.tf-on svg{color:var(--ok);flex:none}

.tf-on-t{font-size:var(--t-h3);font-weight:700;color:var(--ink)}

.tf-on-s{font-size:var(--t-sm);color:var(--muted);margin-top:2px}

.sv-item{align-items:flex-start}

.rows-more{display:flex;justify-content:center;padding:10px 0 6px}

.arc-list{display:flex;flex-direction:column;gap:8px;margin-top:4px}

.arc-row{display:flex;align-items:center;gap:12px;padding:13px 15px;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-md);box-shadow:var(--shadow-xs),inset 0 1px 0 var(--edge-hi)}

.arc-emoji{width:34px;height:34px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;font-size:var(--t-h2);flex:none}

.arc-main{flex:1;min-width:0}

.arc-name{font-size:var(--t-h3);font-weight:600;color:var(--ink)}

.arc-sub{font-size:var(--t-sm);color:var(--faint);margin-top:2px}

@media(max-width:640px){.arc-row{flex-wrap:wrap}.arc-main{flex:1 0 60%}}

.au-list{margin-top:8px;max-height:320px;overflow-y:auto;border:1px solid var(--line);border-radius:var(--r-sm)}

.au-row{display:grid;grid-template-columns:76px 150px 1fr 110px;gap:8px;padding:7px 10px;font-size:var(--t-sm);border-bottom:1px solid var(--line);align-items:center}

.au-row:last-child{border-bottom:0}

.au-when{font-family:var(--mono);color:var(--faint)}

.au-act{font-weight:600;color:var(--ink)}

.au-tgt{color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.au-who{color:var(--faint);text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

@media(max-width:640px){.au-row{grid-template-columns:1fr;gap:2px;padding:9px 10px}.au-who{text-align:left}}

.sg-row{display:flex;align-items:center;gap:11px;padding:9px 0;border-bottom:1px solid var(--line)}

.sg-row:last-child{border-bottom:0}

.sg-dot{width:8px;height:8px;border-radius:50%;flex:none;background:var(--faint)}

.sg-row.ok .sg-dot{background:var(--ok)}

.sg-row.warn .sg-dot{background:var(--warn)}

.sg-row.bad .sg-dot{background:var(--danger)}

.sg-main{flex:1;min-width:0}

.sg-t{font-size:var(--t-body);font-weight:600;color:var(--ink)}

.sg-d{font-size:var(--t-xs);color:var(--faint);margin-top:2px;line-height:1.45}

.sg-num{font-family:var(--mono);font-size:var(--t-h3);font-weight:700;color:var(--ink-2);flex:none}
/* ==== components.072.css ==== */
.ob-card{background:var(--surface);border:1px solid var(--line);border-left:3px solid var(--accent);border-radius:var(--r-lg);padding:20px 22px;margin-bottom:20px;box-shadow:var(--shadow-sm),inset 0 1px 0 var(--edge-hi)}
/* ==== utilities.102.css ==== */
.ob-head{margin-bottom:14px}

.ob-title{font-size:var(--t-h2);font-weight:700;color:var(--ink)}

.ob-sub{font-size:var(--t-sm);color:var(--muted);margin-top:4px;line-height:1.5;max-width:620px}

.ob-step{display:flex;align-items:center;gap:12px;padding:11px 0;border-top:1px solid var(--line)}

.ob-num{width:22px;height:22px;border-radius:50%;background:var(--accent);color:var(--on-solid);font-size:var(--t-sm);font-weight:700;display:flex;align-items:center;justify-content:center;flex:none}

.ob-step.done .ob-num{background:var(--ok)}

.ob-main{flex:1;min-width:0}

.ob-t{font-size:var(--t-body);font-weight:600;color:var(--ink)}

.ob-step.done .ob-t{color:var(--muted);text-decoration:line-through}

.ob-d{font-size:var(--t-sm);color:var(--faint);margin-top:2px;line-height:1.45}

.ob-foot{font-size:var(--t-xs);color:var(--faint);border-top:1px solid var(--line);margin-top:6px;padding-top:10px;line-height:1.5}
/* ==== layout.021.css ==== */
.nav-item-ghost{color:var(--faint)}

.nav-item-ghost:hover{color:var(--accent)}
/* ==== utilities.103.css ==== */
@media(max-width:600px){.ob-step{flex-wrap:wrap}.ob-step .btn{margin-left:34px}}

/* ============================================================
   РЕЙКА УБРАНА (аудит навигации)
   Раньше слева стояла вторая, внешняя полоса разделов, и левое
   меню показывало ровно ОДНУ группу из четырёх — ту, что выбрана
   на рейке. Из этого следовали сразу три проблемы, ради которых
   и затевался аудит: до «Целей» или «Архива» было не одно нажатие,
   а два; переключение рейки прятало все остальные разделы, поэтому
   по левому меню нельзя было понять, где ты находишься и что
   вообще есть в продукте; и один и тот же список приходилось
   держать в двух состояниях — узкая полоса и широкое меню.
   Теперь все группы видны одновременно — ровно так, как это уже
   работало на телефоне, где рейки никогда и не было. Ни один
   раздел не исчез и не переехал: исчез только промежуточный
   уровень между человеком и разделом. */
#rail{display:none!important}

.side-group{display:block}
/* ==== features.032.css ==== */
/* Явная граница над «Проектами» — пользовательский контент отделён
   от системных разделов линией, а не просто отступом, как и просили:
   отступ можно принять за случайность вёрстки, линию — нет. */
.side-group-projects{border-top:1px solid var(--line-2);margin-top:6px;padding-top:10px}
/* ==== utilities.104.css ==== */
.side-group-title{display:flex;align-items:center;font-size:var(--t-micro);font-weight:600;color:var(--faint);padding:16px 12px 5px}

.side-group:first-child .side-group-title{padding-top:4px}

.side-group-add{margin-left:auto;width:22px;height:22px;border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;color:var(--faint);transition:var(--dur-instant);flex-shrink:0}

.side-group-add:hover{background:var(--surface-3);color:var(--ink-2)}

.collapsed .side-group-title{justify-content:center;font-size:0;padding:10px 0 2px}

.collapsed .side-group-add{display:none}

.st-page{max-width:100%;padding:22px var(--gutter) 64px}

.st-head{padding:26px var(--gutter) 0;background:var(--canvas);margin-bottom:20px}

.st-body{padding:0}
/* ==== components.073.css ==== */
/* ---- Billing / Pricing ---- */
.bl-card{border:1px solid var(--line);border-radius:var(--r-xl);padding:18px;background:var(--surface)}
/* ==== utilities.105.css ==== */
.bl-plan-row{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;flex-wrap:wrap}

.bl-plan-name{font-size:20px;font-weight:700;color:var(--ink)}

.bl-plan-sub{font-size:var(--t-sm);color:var(--muted);margin-top:3px}

.bl-plan-price{font-size:var(--t-display);font-weight:700;color:var(--ink);white-space:nowrap}

.bl-plan-per{font-size:var(--t-sm);font-weight:500;color:var(--muted);margin-left:3px}

.bl-meta{font-size:var(--t-body);color:var(--muted);margin-top:8px}

.bl-usage{margin-top:12px}

.bl-usage-h{display:flex;justify-content:space-between;font-size:var(--t-body);margin-bottom:5px}

.bl-usage-n{color:var(--muted);font-variant-numeric:tabular-nums}

.bl-usage-n.over{color:var(--danger);font-weight:600}

.bl-bar{height:6px;border-radius:3px;background:var(--line);overflow:hidden}

.bl-bar-f{height:100%;background:var(--accent);border-radius:3px;transition:width var(--dur)}

.bl-bar-f.over{background:var(--danger)}

.bl-actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:20px}

.pr-wrap{max-width:1180px;margin:0 auto;padding:28px 20px 60px}

.pr-head{text-align:center;margin-bottom:28px}

.pr-title{font-size:30px;font-weight:800;color:var(--ink);margin:0 0 16px}
/* ==== components.074.css ==== */
.pr-toggle{display:inline-flex;gap:2px;padding:3px;border:1px solid var(--line);border-radius:var(--r-pill);background:var(--surface)}
/* ==== utilities.106.css ==== */
.pr-tg{background:0;border:0;padding:8px 18px;border-radius:var(--r-pill);font-size:var(--t-body);font-weight:600;color:var(--muted);cursor:pointer}

.pr-tg.on{background:var(--accent);color:var(--on-solid)}

.pr-save{font-size:var(--t-xs);font-weight:600;opacity:.85}
/* ==== layout.022.css ==== */
.pr-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:14px;align-items:start}
/* ==== components.075.css ==== */
.pr-card{border:1px solid var(--line);border-radius:var(--r-2xl);padding:20px 18px;background:var(--surface);display:flex;flex-direction:column;gap:10px}

.pr-card.feat{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}

.pr-card.cur{background:var(--surface-2)}
/* ==== utilities.107.css ==== */
.pr-name{font-size:var(--t-lg);font-weight:700;color:var(--ink)}

.pr-price{font-size:26px;font-weight:800;color:var(--ink)}

.pr-per{font-size:var(--t-sm);font-weight:500;color:var(--muted);margin-left:4px}

.pr-lim{font-size:var(--t-sm);color:var(--muted);display:flex;flex-direction:column;gap:3px}

.pr-feats{display:flex;flex-direction:column;gap:3px;font-size:var(--t-sm);margin-top:2px}

.pr-f{color:var(--ink)}

.pr-f.off{color:var(--faint)}

.pr-trial{margin-top:-4px}

.pr-trial-note{font-size:var(--t-xs);color:var(--faint);text-align:center}

@media(max-width:720px){.pr-grid{grid-template-columns:1fr}.pr-title{font-size:24px}}
/* ==== components.076.css ==== */
.st-tabs{display:flex;gap:2px;border-bottom:1px solid var(--line);margin-bottom:26px;overflow-x:auto}

.st-tab{background:0;border:0;padding:9px 14px;font-size:var(--t-body);font-weight:600;color:var(--muted);cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px;white-space:nowrap;transition:color var(--dur-instant)}

.st-tab:hover{color:var(--ink)}

.st-tab.active{color:var(--accent-700);border-bottom-color:var(--accent)}

[data-theme="dark"] .st-tab.active{color:var(--accent-600)}
/* ==== utilities.108.css ==== */
.st-section{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);padding:22px 24px;margin-bottom:18px;box-shadow:var(--shadow-sm),inset 0 1px 0 var(--edge-hi)}

.st-sec-title{font-size:var(--t-xs);font-weight:600;color:var(--faint);margin-bottom:16px;padding-bottom:12px;border-bottom:1px solid var(--line)}

.st-fld{margin-bottom:16px;display:flex;flex-direction:column;gap:6px}

.st-fld-t{font-size:var(--t-sm);font-weight:500;color:var(--muted)}

.st-fld-v{font-size:var(--t-body);color:var(--ink);line-height:1.5}

.st-fld-ro{color:var(--muted)}

.st-sel{max-width:260px}

.st-row{display:flex;align-items:center;gap:14px;margin-bottom:14px}

.st-ava{width:52px;height:52px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:var(--t-lg);font-weight:700;color:var(--on-solid);flex:none}
/* ==== components.077.css ==== */
.st-toggle-row{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:10px 0;border-bottom:1px solid var(--line)}

.st-toggle-row:last-child{border-bottom:0}
/* ==== utilities.109.css ==== */
.st-ntf-group{transition:opacity var(--dur-fast)}

.st-ntf-group.dimmed{opacity:.42;pointer-events:none}

.st-switch{position:relative;width:38px;height:22px;flex:none;cursor:pointer}
/* ==== components.078.css ==== */
.st-switch input{opacity:0;width:0;height:0;position:absolute}
/* ==== utilities.110.css ==== */
.st-sw-slider{position:absolute;inset:0;background:var(--line-3);border-radius:var(--r-xl);transition:var(--dur);box-shadow:inset 0 1px 2px rgba(0,0,0,.12)}

.st-sw-slider:before{content:'';position:absolute;width:16px;height:16px;left:3px;bottom:3px;background:#fff;border-radius:50%;transition:var(--dur);box-shadow:0 1px 3px rgba(0,0,0,.25)}
/* ==== components.079.css ==== */
.st-switch input:checked+.st-sw-slider{background:var(--accent)}

.st-switch input:checked+.st-sw-slider:before{transform:translateX(16px)}

/* Сам чекбокс сжат до 0×0 и невидим (см. .st-switch input выше) —
   значит обычный outline на нём самом на экране не виден вообще,
   хотя переключатель прекрасно фокусируется и переключается Space.
   Кольцо фокуса переносится на видимый .st-sw-slider тем же приёмом
   соседнего селектора, что уже используется для состояния :checked. */
.st-switch input:focus-visible+.st-sw-slider{box-shadow:0 0 0 2px var(--canvas),0 0 0 4px var(--accent),inset 0 1px 2px rgba(0,0,0,.12)}

/* У .auto-switch (автоматизации) это правило уже было —
   .auto-switch input:disabled+.auto-sw-slider{opacity:.45}. У более
   общего .st-switch (используется в разделах Настроек, включая обе
   push-секции) такого правила не было никогда — задизейбленный
   переключатель отрисовывался ВИЗУАЛЬНО неотличимым от активного:
   тот же насыщенный цвет заливки, тот же вид, только клик по нему
   ничего не делал. Найдено не чтением кода, а прямым кликом по
   интерфейсу в браузере: категории push при выключенном мастер-
   переключателе выглядели включёнными и активными, хотя были
   disabled. Тот же класс проблемы затрагивал и старый pushToggle
   (VAPID), когда SYNC.url не задан, — просто был не так заметен,
   потому что это единственный переключатель, а не семь подряд. */
.st-switch input:disabled+.st-sw-slider{opacity:.45;cursor:not-allowed}
/* ==== utilities.111.css ==== */
.st-sw-dim .st-sw-slider{opacity:.4;cursor:not-allowed}

.st-foot{display:flex;gap:8px;margin-top:16px;flex-wrap:wrap}

.sv-main{display:flex;flex-direction:column;min-width:0;flex:1}

.sv-name{font-size:var(--t-body);color:var(--ink);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.sv-sub{font-size:var(--t-xs);color:var(--faint);margin-top:1px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.sv-del{opacity:0;color:var(--faint);display:flex;padding:2px;border-radius:var(--r-xs);flex:none;margin-left:6px}

.sv-item:hover .sv-del{opacity:1}

.sv-del:hover{background:var(--danger-soft);color:var(--danger)}

.auth-code{font-family:var(--mono);font-size:var(--t-lg);letter-spacing:4px;text-align:center}

.tf-codes{background:var(--canvas);border:1px solid var(--line);border-radius:var(--r-sm);padding:11px 13px;font-family:var(--mono);font-size:var(--t-body);line-height:1.8;margin:8px 0;user-select:all}
/* ==== features.033.css ==== */
.guide-doc{max-width:780px;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);padding:26px 30px;font-size:var(--t-h3);line-height:1.75;color:var(--ink-2);box-shadow:var(--shadow-sm),inset 0 1px 0 var(--edge-hi)}

.guide-doc .rich-h1,.guide-doc h1{font-size:24px;font-weight:700;letter-spacing:-.03em;color:var(--ink);margin:0 0 16px}

.guide-doc .rich-h2,.guide-doc h2{font-size:var(--t-h2);font-weight:700;color:var(--ink);margin:22px 0 8px}

.guide-doc .rich-h3,.guide-doc h3{font-size:var(--t-h3);font-weight:700;color:var(--ink);margin:16px 0 6px}

.guide-doc ul,.guide-doc ol{margin:6px 0 10px;padding-left:22px}

.guide-doc li{margin:4px 0}

.guide-doc strong{color:var(--ink)}

.guide-doc p{margin:8px 0}

.guide-doc hr{border:0;border-top:1px solid var(--line);margin:18px 0}

.guide-doc em{color:var(--faint)}

.guide-area{width:100%;max-width:780px;min-height:60vh;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-md);padding:16px 18px;color:var(--ink);font-family:var(--mono);font-size:var(--t-sm);line-height:1.6;outline:0;resize:vertical}

.guide-area:focus{border-color:var(--accent)}
/* ==== components.080.css ==== */
.guide-card{display:flex;align-items:center;gap:14px;background:var(--surface);border:1px solid var(--accent-line);border-left:3px solid var(--accent);border-radius:var(--r-md);padding:14px 16px;margin-bottom:18px;box-shadow:var(--shadow-sm),inset 0 1px 0 var(--edge-hi)}
/* ==== utilities.112.css ==== */
.gc-ic{color:var(--accent);flex:none}

.gc-main{flex:1;min-width:0}

.gc-t{font-size:var(--t-h3);font-weight:700;color:var(--ink)}

.gc-s{font-size:var(--t-sm);color:var(--muted);margin-top:2px;line-height:1.45}

@media(max-width:600px){.guide-doc{padding:16px 15px;font-size:var(--t-body)}.guide-card{flex-wrap:wrap}}

@supports(padding:env(safe-area-inset-bottom)){
  #sidebar{padding-bottom:env(safe-area-inset-bottom)}
  #panel{padding-bottom:env(safe-area-inset-bottom)}
  .bulk-bar{bottom:calc(16px + env(safe-area-inset-bottom))}
  .verify-bar{bottom:calc(18px + env(safe-area-inset-bottom))}
  #toastRoot{bottom:calc(20px + env(safe-area-inset-bottom))}
}

.bk-row.tm-off{opacity:.6}
/* ==== base.007.css ==== */
/* ============================================================
   СЕЛЕКТОРЫ СКРЫТИЯ ДЛЯ ГОСТЕЙ БЫЛИ МЁРТВЫМИ
   [data-act="quick-add"] и [data-act="add-sub"] не совпадали ни с
   одним реальным элементом — кнопка быстрого добавления задачи
   называется data-act="add-task-quick", а поле подзадачи вообще не
   имеет data-act, это классы .add-sub-input/.add-sub-inline.
   Сервер всё равно отклоняет запись от гостя (can_write() в
   api.php), поэтому потери данных не было — но гость видел рабочие
   на вид поля, вводил текст, а сохранение молча не проходило.
   Со стороны это выглядит как «ToDoList не работает», а не как
   «у меня недостаточно прав». Исправлено на актуальные селекторы. */
body.role-guest .add-task-input,body.role-guest [data-act="new-task"],body.role-guest [data-act="new-project"],body.role-guest [data-act="create-menu"],body.role-guest [data-act="add-section"],body.role-guest .comment-box:not(.pm-composer),body.role-guest [data-act="add-task-quick"],body.role-guest .row-sel,body.role-guest [data-act="upload-file"],body.role-guest [data-act="add-attach"],body.role-guest .add-sub-inline,body.role-guest .add-sub-input{display:none!important}

body.role-guest .task-check,body.role-guest .card-check{pointer-events:none;opacity:.55}
/* ==== utilities.113.css ==== */
@media(max-width:600px){.verify-bar{font-size:var(--t-xs);padding:8px 10px}}

#legalGate{position:fixed;inset:0;z-index:3000;background:rgba(0,0,0,.5);display:none;align-items:center;justify-content:center;padding:20px}

[data-theme="dark"] #legalGate{background:rgba(0,0,0,.68)}

.legal-wrap{width:100%;max-width:640px}
/* ==== components.081.css ==== */
.legal-card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);display:flex;flex-direction:column;max-height:88vh;box-shadow:var(--shadow-lg)}
/* ==== utilities.114.css ==== */
.legal-head{display:flex;align-items:center;justify-content:space-between;padding:15px 20px;border-bottom:1px solid var(--line)}

.legal-title{font-size:var(--t-h2);font-weight:700;color:var(--ink)}

.legal-body{padding:16px 22px;overflow-y:auto;font-size:var(--t-body);color:var(--ink-2);line-height:1.6}

.legal-body h4{font-size:var(--t-body);color:var(--ink);margin:14px 0 4px}

.legal-body p{margin:0 0 8px}

.legal-foot{padding:12px 20px;border-top:1px solid var(--line);text-align:right}

.bk-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:9px 0;border-bottom:1px solid var(--line)}

.bk-name{font-size:var(--t-body);color:var(--ink);font-weight:500}

.bk-sub{font-size:var(--t-xs);color:var(--faint);font-family:var(--mono)}
/* ==== components.082.css ==== */
.modal-lg{max-width:560px;width:100%}

/* Средний размер — тот же принцип, что у .modal-lg: раньше пять
   модалок задавали почти одну и ту же ширину (420/440/460/480px)
   инлайн-стилем по отдельности, ни разу не переиспользуя общий
   класс — тот самый «случайный разброс между страницами». Beрну к
   наиболее частому среди них значению (480px встречалось чаще
   остальных), а не изобретаю новое число. */
.modal-md{max-width:480px;width:100%}
/* ==== utilities.115.css ==== */
.int-sec{padding:12px 0;border-bottom:1px solid var(--line)}

.int-sec:last-child{border-bottom:0}

.int-h{font-size:var(--t-body);font-weight:700;color:var(--ink);margin-bottom:3px}

.int-note{font-size:var(--t-sm);color:var(--muted);line-height:1.45;margin-bottom:8px}

.int-note b{color:var(--ink-2);font-family:var(--mono);font-weight:600}

.int-empty{font-size:var(--t-sm);color:var(--faint);padding:4px 0}

.int-add{display:flex;gap:8px;margin-top:8px}
/* ==== components.083.css ==== */
.int-add .form-input{flex:1}
/* ==== utilities.116.css ==== */
/* ============================================================
   КАРТОЧКИ ПЛОЩАДОК — ЕДИНЫЙ РАЗДЕЛ INTEGRATIONS
   Сетка карточек, сгруппированных по категориям (чат, календарь,
   файлы, разработка, встречи) — та же плотная, но читаемая раскладка,
   что и у .chart-card в Dashboard, специально не изобретал новый
   визуальный язык для ещё одного раздела настроек. */
.int-cat-title{font-size:var(--t-xs);font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--faint);margin:18px 0 8px}

.int-cat-title:first-child{margin-top:0}
/* ==== layout.023.css ==== */
.int-card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:12px;margin-bottom:4px}
/* ==== components.084.css ==== */
.int-card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);padding:14px 15px;display:flex;flex-direction:column;gap:6px}

.int-card-head{display:flex;align-items:center;gap:8px}

.int-card-dot{width:8px;height:8px;border-radius:50%;background:var(--line-3);flex-shrink:0}

.int-card-dot.on{background:var(--ok)}

.int-card-dot.warn{background:var(--danger)}

.int-card-name{font-size:var(--t-body);font-weight:700;color:var(--ink)}

.int-card-desc{font-size:var(--t-sm);color:var(--muted);line-height:1.4}

.int-card-status{font-size:var(--t-xs);color:var(--faint);font-weight:600}

.int-card-meta{display:flex;flex-direction:column;gap:4px;margin-top:2px}

.int-card-label{font-size:var(--t-sm);font-weight:600;color:var(--ink-2)}

.int-card-sub{font-size:var(--t-xs);color:var(--faint)}

.int-card-err{font-size:var(--t-xs);color:var(--danger);display:flex;align-items:flex-start;gap:5px;line-height:1.4;background:var(--danger-soft);border-radius:var(--r-sm);padding:6px 8px;margin-top:2px}

.int-card-scope{font-size:var(--t-xs);color:var(--muted);display:flex;align-items:center;gap:6px;flex-wrap:wrap}
/* ==== utilities.117.css ==== */
.int-scope-sel{font-size:var(--t-xs);padding:3px 6px;border:1px solid var(--line-2);border-radius:var(--r-xs);background:var(--surface-2);color:var(--ink-2);max-width:130px}
/* ==== components.085.css ==== */
.int-card-actions{display:flex;gap:6px;margin-top:4px}

.int-card-actions .btn{flex:1;justify-content:center}

.int-connect-form{margin-top:8px;padding-top:8px;border-top:1px solid var(--line-2)}
/* ==== utilities.118.css ==== */
.int-connect-actions{display:flex;gap:8px;justify-content:flex-end}

.int-copy{font-family:var(--mono);font-size:var(--t-xs)}

.int-trunc{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ===== burger + mobile nav scrim + shortcuts ===== */
.tb-burger{display:none;width:36px;height:36px;border-radius:var(--r-md);align-items:center;justify-content:center;color:var(--ink-2);flex-shrink:0}

.tb-burger:hover{background:var(--line-2)}
/* ==== layout.024.css ==== */
.nav-scrim{display:none;position:fixed;inset:0;background:rgba(0,0,0,.4);z-index:75}
/* ==== utilities.119.css ==== */
.sc-row{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:9px 2px;border-bottom:1px solid var(--line-2)}

.sc-row:last-child{border-bottom:none}

.sc-keys{font-family:var(--mono);font-size:var(--t-xs);background:var(--surface-2);border:1px solid var(--line);border-bottom-width:2px;border-radius:var(--r-xs);padding:3px 9px;color:var(--ink-2);white-space:nowrap;flex-shrink:0}

.sc-desc{font-size:var(--t-body);color:var(--ink-2)}

/* ===== mobile (phones/tablets) ===== */
@media(max-width:768px){
  #app{grid-template-columns:1fr!important}
  #sidebar{position:fixed;top:0;left:0;bottom:0;width:min(86vw,300px);z-index:80;transform:translateX(-100%);transition:transform var(--dur-slow) cubic-bezier(.4,0,.2,1);box-shadow:var(--shadow-lg)}
  #app.nav-open #sidebar{transform:translateX(0)}
  #app.nav-open ~ .nav-scrim{display:block}
  .tb-burger{display:flex}
  .side-collapse{display:none}
  #panel{width:100vw!important;max-width:100vw!important}
  #modalRoot{padding:5vh 12px}
  #topbar{padding:0 12px;gap:8px}
  #rail{display:none}
  .tb-create{padding:0 10px}
  .tabs{overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none}
  .tabs::-webkit-scrollbar{display:none}
  .view-toolbar{flex-wrap:wrap;row-gap:6px}
  .prof-head{gap:14px}
  .prof-ava{width:68px;height:68px;font-size:24px}
  .prof-name{font-size:var(--t-lg)}
  .cm-tabs{gap:10px;flex-wrap:wrap}
  .cm-sort{padding-bottom:4px}
  .tb-search{display:none}
  .list-colhead,.task-row{grid-template-columns:1fr 30px!important}
  /* n+3 раньше прятал вообще всё после исполнителя — включая кнопку
     «···», которая на самом деле стоит одной из последних в строке.
     На узком телефоне это означало, что второстепенные действия
     (дублировать, прикрепить файл, удалить) переставали быть
     доступны из списка вообще, без открытия задачи — не «убрали
     лишнее», а случайно отрезали рабочую функцию. Прячем по имени
     класса, а не по номеру потомка: работает одинаково, сколько бы
     дополнительных полей проекта ни было. */
  .list-colhead .ch:nth-child(n+3),.task-row .cell-assignee~*:not(.row-more){display:none!important}
  .dash-wrap{grid-template-columns:repeat(2,1fr)}
  .dash-wrap .stat-card{grid-column:span 1}
  .dash-wrap .chart-card.half,.dash-wrap .chart-card.full,.dash-wrap .status-card{grid-column:span 2}
  .home-grid{grid-template-columns:1fr}
  .view-toolbar{flex-wrap:wrap;height:auto;padding-top:10px;padding-bottom:10px}
  .cal-head{flex-wrap:wrap;gap:10px}
  .cal-wrap{overflow-x:auto}
  .cal-grid{min-width:620px}
  .cal-cell{min-height:74px;padding:3px 4px}
  .cal-ev{font-size:var(--t-micro);padding:2px 5px}
  .cal-grid.week .cal-cell{min-height:300px}
  .page-head,.view-toolbar,.list-wrap,.board-wrap,.cal-wrap,.dash-wrap,.home-wrap,.goals-wrap,.pf-wrap,.inbox-wrap{padding-left:12px;padding-right:12px}
  .board-col{min-width:80vw}
  .board-col.collapsed{min-width:46px!important}
  .pf-row{grid-template-columns:1.4fr 1fr!important}
  .pf-row>*:nth-child(n+3){display:none!important}
}
/* ==== layout.025.css ==== */
/* ============================================================
   ВИЗУАЛЬНАЯ ИЕРАРХИЯ — завершающий слой
   Здесь собрано то, что действует поперёк всех экранов:
   шкала кегля, поднятые плоскости, состояния и микроанимация.
   ============================================================ */

/* --- 1. Кегль и насыщенность --------------------------------
   Пять чётких ступеней вместо кучи близких размеров.          */
.ph-title,.home-greet,.prof-name,.panel-name{font-weight:700}
/* ==== components.086.css ==== */
.modal-title,.cal-title,.empty-title,.goal-title,.dg-st-lbl,.int-h,.legal-title,.gc-t,.ob-title,.tf-on-t{
  font-size:var(--t-h2);font-weight:700;letter-spacing:-.025em;color:var(--ink);
}
/* ==== utilities.120.css ==== */
.widget-title,.chart-title,.section-title,.pc-name,.sg-t,.fld-name,.arc-name{
  font-size:var(--t-h3);font-weight:700;letter-spacing:-.02em;color:var(--ink);
}
/* ==== layout.026.css ==== */
/* надзаголовки и подписи разделов — моноширинные, разрежённые */
.nav-label,.list-colhead .ch,.pf-thead,.inbox-day,.tl-sec-label,.modal-sub,
.panel-sec-title,.st-sec-title,.prof-card-title,.pp-head,.menu-head,.ph-eyebrow,.ring-cap{
  font-variant-numeric:tabular-nums;
}
/* ==== components.087.css ==== */
/* цифры всегда табличные — колонки не «пляшут» */
.stat-value,.hk-num,.ring-pct,.bc-count,.section-count,.pf-prog-num,.sg-num,.badge{
  font-variant-numeric:tabular-nums;letter-spacing:-.02em;
}

/* --- 2. Поднятые плоскости ----------------------------------
   Любая карточка получает световую кромку сверху: так плоскость
   читается как физическая, а не как прямоугольник с рамкой.    */
.widget,.stat-card,.chart-card,.goal-card,.person-card,.prof-card,.st-section,
.pf-table,.file-card,.arc-row,.ob-card,.guide-card,.guide-doc,.wl-row,.modal,.menu{
  background-clip:padding-box;
}

[data-theme="dark"] .card,
[data-theme="dark"] .widget,
[data-theme="dark"] .stat-card,
[data-theme="dark"] .chart-card,
[data-theme="dark"] .goal-card,
[data-theme="dark"] .st-section,
[data-theme="dark"] .prof-card,
[data-theme="dark"] .person-card,
[data-theme="dark"] .pf-table,
[data-theme="dark"] .modal,
[data-theme="dark"] .menu{border-color:var(--line)}

/* --- 3. Состояния -------------------------------------------
   Отметка выполнения «наливается» цветом, а не мигает.         */
.task-check,.card-check,.mini-check,.sub-check{transition:background var(--dur),border-color var(--dur),box-shadow var(--dur)}

.task-check:hover,.card-check:hover,.mini-check:hover,.sub-check:hover{border-color:var(--ok);box-shadow:0 0 0 3px var(--ok-soft)}

.task-row.done .task-check,.card.done .card-check,.mini-task.done .mini-check,.subtask.done .sub-check{
  box-shadow:0 0 0 3px var(--ok-soft);
}

.task-row.done,.card.done{opacity:.72}

.task-row.done:hover,.card.done:hover{opacity:1}
/* ==== features.034.css ==== */
/* строка задачи под курсором чуть «выезжает» из ряда */
.task-row{margin:0 -4px;padding-left:16px;padding-right:16px}
/* ==== utilities.121.css ==== */
/* заголовок первой колонки встаёт ровно над названиями задач,
   а не над зоной галочки — колонка читается как единое целое */
@media(min-width:769px){.list-colhead{padding-left:98px}}

@media(max-width:768px){.list-colhead{padding-left:44px}}
/* ==== components.088.css ==== */
/* --- 4. Поля ввода ------------------------------------------ */
.form-input,.field-input,.desc-area,.auth-in,.tb-search input,.comment-input-wrap{
  transition:border-color var(--dur-fast),box-shadow var(--dur-fast),background var(--dur-fast);
}

.form-input:hover:not(:focus),.field-input:hover:not(:focus),.desc-area:hover:not(:focus){border-color:var(--line-3)}

input::placeholder,textarea::placeholder{color:var(--faint)}
/* ==== layout.027.css ==== */
/* --- 5. Кнопки и чипы: отклик на нажатие --------------------- */
.btn,.chip,.tb-icon,.tb-create,.btn-create,.menu-item,.nav-item,.proj-item{
  -webkit-tap-highlight-color:transparent;
}
/* ==== utilities.122.css ==== */
.chip:active,.tb-icon:active{transform:scale(.97)}
/* ==== components.089.css ==== */
/* --- 6. Разделители: тоньше и реже --------------------------- */
.mini-task:last-child,.subtask:last-child,.fld-row:last-child,
.sg-row:last-child,.st-toggle-row:last-child{border-bottom:none}

/* --- 7. Всплывающие слои ------------------------------------- */
.pp-pop,.menu{box-shadow:var(--shadow-lg),inset 0 1px 0 var(--edge-hi)}
/* ==== utilities.123.css ==== */
.pp-box{background:var(--surface-2);box-shadow:var(--ring)}

.pp-sug:hover{background:var(--surface-3)}

/* --- 8. Прогресс и графики ----------------------------------- */
.pf-prog-fill,.wl-bar>div{box-shadow:inset 0 1px 0 rgba(255,255,255,.22)}

/* --- 9. Тонкая настройка тёмной темы -------------------------
   На тёмном фоне заливки статусов должны быть прозрачными,
   иначе плашки «отклеиваются» от карточки.                     */
[data-theme="dark"] .cal-cell.today{background:var(--accent-soft-2)}
/* ==== layout.028.css ==== */
[data-theme="dark"] .cal-grid{background:var(--surface)}
/* ==== utilities.124.css ==== */
[data-theme="dark"] .empty-ic,
[data-theme="dark"] .home-kpi,
[data-theme="dark"] .prof-chip{background:var(--surface-2)}

[data-theme="dark"] .sc-keys,
[data-theme="dark"] .rich-code,
[data-theme="dark"] .dg-log,
[data-theme="dark"] .tf-codes{background:var(--well)}

/* --- 10. Печать и доступность -------------------------------- */
@media(prefers-contrast:more){
  :root{--line:#c9ccd8;--line-2:#dfe2ea;--muted:#4a4d63}
  [data-theme="dark"]{--line:#3c414f;--line-2:#333846;--muted:#a3a8bc}
}
/* ==== components.090.css ==== */
/* --- 11. Текст поверх произвольных цветов ---------------------
   Аватары и полосы диаграмм красятся цветом участника/проекта.
   Ровный тёмный подслой поднимает контраст белых подписей,
   не трогая сам цвет (он задаётся в разметке).                 */
.avatar,.prof-ava,.st-ava,.tf-num,.ob-num{box-shadow:inset 0 0 0 999px rgba(0,0,0,.26),inset 0 0 0 1px rgba(0,0,0,.1),inset 0 1px 0 rgba(255,255,255,.14);font-weight:700}

.avatar-stack .avatar,.avatar-add{box-shadow:inset 0 0 0 999px rgba(0,0,0,.24)}
/* ==== utilities.125.css ==== */
.bar-fill{text-shadow:0 1px 2px rgba(0,0,0,.45)}

.ring-pct{color:var(--ink)!important}

.cal-dow{color:var(--muted)}

.inbox-time,.act-time,.comment-time,.au-when{color:var(--muted)}
/* ==== base.008.css ==== */
/* ============================================================
   СИСТЕМА АНИМАЦИЙ — единый слой движения поверх всего интерфейса
   Длительности 150–250ms, фирменный набор кривых, микроанимации
   при наведении, переходах между разделами, drag&drop и смене
   состояний. Все анимации отключаются через prefers-reduced-motion
   (правило уже объявлено в базовом слое).
   ============================================================ */

:root{
  /* --- длительности --- */
  --dur-instant:100ms;
  --dur-fast:150ms;
  --dur:200ms;
  --dur-slow:250ms;
  --dur-panel:320ms;

  /* --- кривые --- */
  --ease-out:cubic-bezier(.16,1,.3,1);        /* решительный выход, для появления */
  --ease-in-out:cubic-bezier(.65,0,.35,1);    /* симметричные переходы */
  --ease-standard:cubic-bezier(.4,0,.2,1);    /* дефолт для смены состояний */
  --ease-spring:cubic-bezier(.34,1.56,.64,1); /* лёгкий перехлёст — модалки, чекбоксы */
  --ease-snap:cubic-bezier(.2,0,0,1);         /* быстрый уверенный отклик — кнопки */
}
/* ==== layout.029.css ==== */
/* --- 0. Общий обмен: transform/opacity дешевле всего для браузера --- */
.task-row,.card,.nav-item,.proj-item,.tab,.chip,.btn,.menu-item,
.widget,.stat-card,.chart-card,.goal-card,.person-card,.file-card,.inbox-item,
.pf-row,.mini-task,.proj-tile,.person-tile,.home-kpi,.cal-ev,.cal-cell,
.board-col,.emoji-pick,.swatch,.avatar,.tb-icon,.side-collapse,
.panel-close,.modal-x,.bc-menu,.sh-actions button,.dep-del,.attach-dl,
.sv-del,.mh-x,.sub-del,.tag-x{
  will-change:transform;
}

/* ============================================================ 1. НАВИГАЦИЯ */
/* Смена раздела — контент лёгким движением въезжает снизу.
   Класс ставится в go() только при переходе между разделами,
   точечные обновления внутри раздела (чек, drag) его не задевают. */
@keyframes navEnter{
  from{opacity:0;transform:translateY(6px)}
  to{opacity:1;transform:translateY(0)}
}

#main.nav-enter{animation:navEnter var(--dur-slow) var(--ease-out)}

/* Рейка: вертикальная черта у активного раздела едет плавно */


/* Боковая панель: пункты, проекты */
.nav-item,.proj-item{transition:background var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard)}

.nav-item svg{transition:color var(--dur-fast) var(--ease-standard),transform var(--dur-fast) var(--ease-snap)}

.nav-item:active,.proj-item:active{transform:scale(.985)}
/* ==== utilities.126.css ==== */
.side-collapse svg{transition:transform var(--dur-slow) var(--ease-in-out)}

#app.collapsed .side-collapse svg{transform:rotate(180deg)}

.side-collapse{transition:background var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard),transform var(--dur-fast) var(--ease-snap)}

.side-collapse:active{transform:scale(.9)}

/* Разворачивание/сворачивание боковой панели и рабочей области —
   единая кривая на оба направления, чуть длиннее, т.к. двигается вся сетка */
#app{transition:grid-template-columns var(--dur-panel) var(--ease-in-out)}
/* ==== layout.030.css ==== */
#sidebar,.brand-name,.nav-item .lbl,.proj-item .lbl,.btn-create .lbl{
  transition:opacity var(--dur) var(--ease-standard),width var(--dur-panel) var(--ease-in-out);
}
/* ==== components.091.css ==== */
/* Вкладки проекта: подчёркивание переезжает по X/цвету плавно */
.tab{transition:color var(--dur-fast) var(--ease-standard),border-color var(--dur) var(--ease-standard)}

.tab svg{transition:color var(--dur-fast) var(--ease-standard)}

.tab:active{transform:translateY(1px)}

.home-tab{transition:color var(--dur-fast) var(--ease-standard),border-color var(--dur) var(--ease-standard)}
/* ==== utilities.127.css ==== */
/* ============================================================ 2. КАРТОЧКИ И СТРОКИ */
/* Появление элементов списка/доски при первом рендере раздела —
   тонкая, короткая, с небольшим сдвигом по вертикали. Каскад по
   первым элементам создаёт ощущение «раскладки», не задерживая
   восприятие остальных строк. */
@keyframes itemIn{
  from{opacity:0;transform:translateY(5px)}
  to{opacity:1;transform:translateY(0)}
}
/* ==== layout.031.css ==== */
#main.nav-enter .task-row,
#main.nav-enter .card,
#main.nav-enter .goal-card,
#main.nav-enter .stat-card,
#main.nav-enter .chart-card,
#main.nav-enter .widget,
#main.nav-enter .inbox-item,
#main.nav-enter .pf-row,
#main.nav-enter .person-card,
#main.nav-enter .file-card,
#main.nav-enter .proj-tile,
#main.nav-enter .board-col{
  animation:itemIn var(--dur-slow) var(--ease-out) backwards;
}

#main.nav-enter .task-row:nth-child(1),#main.nav-enter .card:nth-child(1),#main.nav-enter .goal-card:nth-child(1),#main.nav-enter .stat-card:nth-child(1),#main.nav-enter .inbox-item:nth-child(1),#main.nav-enter .pf-row:nth-child(1),#main.nav-enter .person-card:nth-child(1),#main.nav-enter .board-col:nth-child(1){animation-delay:0ms}

#main.nav-enter .task-row:nth-child(2),#main.nav-enter .card:nth-child(2),#main.nav-enter .goal-card:nth-child(2),#main.nav-enter .stat-card:nth-child(2),#main.nav-enter .inbox-item:nth-child(2),#main.nav-enter .pf-row:nth-child(2),#main.nav-enter .person-card:nth-child(2),#main.nav-enter .board-col:nth-child(2){animation-delay:22ms}

#main.nav-enter .task-row:nth-child(3),#main.nav-enter .card:nth-child(3),#main.nav-enter .goal-card:nth-child(3),#main.nav-enter .stat-card:nth-child(3),#main.nav-enter .inbox-item:nth-child(3),#main.nav-enter .pf-row:nth-child(3),#main.nav-enter .person-card:nth-child(3),#main.nav-enter .board-col:nth-child(3){animation-delay:44ms}

#main.nav-enter .task-row:nth-child(4),#main.nav-enter .card:nth-child(4),#main.nav-enter .goal-card:nth-child(4),#main.nav-enter .stat-card:nth-child(4),#main.nav-enter .inbox-item:nth-child(4),#main.nav-enter .pf-row:nth-child(4),#main.nav-enter .person-card:nth-child(4),#main.nav-enter .board-col:nth-child(4){animation-delay:66ms}

#main.nav-enter .task-row:nth-child(5),#main.nav-enter .card:nth-child(5),#main.nav-enter .goal-card:nth-child(5),#main.nav-enter .stat-card:nth-child(5),#main.nav-enter .inbox-item:nth-child(5),#main.nav-enter .pf-row:nth-child(5),#main.nav-enter .person-card:nth-child(5){animation-delay:88ms}

#main.nav-enter .task-row:nth-child(6),#main.nav-enter .card:nth-child(6),#main.nav-enter .inbox-item:nth-child(6),#main.nav-enter .pf-row:nth-child(6){animation-delay:110ms}

#main.nav-enter .task-row:nth-child(7),#main.nav-enter .card:nth-child(7),#main.nav-enter .inbox-item:nth-child(7){animation-delay:132ms}

#main.nav-enter .task-row:nth-child(n+8),#main.nav-enter .card:nth-child(n+8),#main.nav-enter .inbox-item:nth-child(n+8){animation-delay:150ms}
/* ==== features.035.css ==== */
/* Наведение: карточки и строки — приподнимаются, а не просто светлеют */
.task-row{transition:background var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard),transform var(--dur-fast) var(--ease-standard)}
/* ==== components.092.css ==== */
.card{transition:box-shadow var(--dur) var(--ease-out),border-color var(--dur-fast) var(--ease-standard),transform var(--dur) var(--ease-out)}

.card:hover{transform:translateY(-2px)}

.card:active{transform:translateY(-1px) scale(.995);transition-duration:var(--dur-instant)}

.goal-card,.stat-card,.widget,.chart-card,.person-card,.file-card{
  transition:box-shadow var(--dur) var(--ease-out),border-color var(--dur-fast) var(--ease-standard),transform var(--dur) var(--ease-out);
}

.goal-card:hover,.person-card:hover,.file-card:hover{transform:translateY(-2px)}

.stat-card:hover,.chart-card:hover,.widget:hover{box-shadow:var(--shadow-md),inset 0 1px 0 var(--edge-hi);transform:translateY(-1px)}
/* ==== features.036.css ==== */
.pf-row,.mini-task,.proj-tile,.person-tile,.inbox-item{transition:background var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard)}
/* ==== utilities.128.css ==== */
.home-kpi{transition:box-shadow var(--dur) var(--ease-out),transform var(--dur) var(--ease-out)}

.home-kpi:hover{transform:translateY(-2px);box-shadow:var(--shadow-md),inset 0 1px 0 var(--edge-hi)}
/* ==== components.093.css ==== */
/* ============================================================ 3. СОСТОЯНИЯ ЗАДАЧ */
/* Чекбокс: лёгкий перехлёст при отметке, без прыжков при обычном рендере */
.task-check,.card-check,.mini-check,.sub-check{
  transition:background var(--dur) var(--ease-spring),border-color var(--dur) var(--ease-standard),
             box-shadow var(--dur) var(--ease-standard),transform var(--dur-fast) var(--ease-snap);
}

.task-check:active,.card-check:active,.mini-check:active,.sub-check:active{transform:scale(.85)}

.task-check svg,.card-check svg,.mini-check svg,.sub-check svg{
  transition:opacity var(--dur-fast) var(--ease-standard),transform var(--dur) var(--ease-spring);
}

.task-row.done .task-check svg,.card.done .card-check svg,.mini-task.done .mini-check svg,.subtask.done .sub-check svg{
  transform:scale(1);
}

/* название задачи гаснет с небольшой задержкой после отметки — глаз успевает увидеть чек */
.task-name,.card-title,.mini-name,.sub-name{transition:color var(--dur-slow) var(--ease-standard) var(--dur-fast)}

/* строки/карточки, помеченные выполненными — плавное затухание, а не рывок */
.task-row,.card.done{transition:background var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard),transform var(--dur) var(--ease-standard),opacity var(--dur-slow) var(--ease-standard)}

/* ============================================================ 4. КНОПКИ И ЧИПЫ */
.btn{transition:background var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard),
     color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard),transform var(--dur-fast) var(--ease-snap)}

.btn:active{transform:scale(.965)}

.btn-primary:hover,.tb-create:hover{transform:translateY(-1px)}

.btn-primary:active,.tb-create:active{transform:translateY(0) scale(.97)}

.btn-create{transition:background var(--dur-fast) var(--ease-standard),transform var(--dur-fast) var(--ease-snap),box-shadow var(--dur-fast) var(--ease-standard)}

.btn-create:hover{transform:translateY(-1px);box-shadow:var(--shadow),inset 0 1px 0 rgba(255,255,255,.18)}

.btn-create:active{transform:translateY(0) scale(.97)}
/* ==== utilities.129.css ==== */
.chip{transition:background var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard),transform var(--dur-fast) var(--ease-snap)}

.chip:active{transform:scale(.95)}

.tb-icon{transition:background var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard),transform var(--dur-fast) var(--ease-snap)}

.tb-icon:hover{transform:translateY(-1px)}

.tb-icon:active{transform:scale(.9)}

.tb-icon .dot{transition:transform var(--dur) var(--ease-spring)}
/* ==== components.094.css ==== */
.tb-search input{transition:background var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur) var(--ease-standard)}

/* аватары — лёгкий отклик там, где они кликабельны (в стопке участников, списках) */
.avatar-stack .avatar,.pp-sug .avatar,.person-tile .avatar{transition:transform var(--dur-fast) var(--ease-snap)}

.avatar-stack .avatar:hover{transform:translateY(-2px) scale(1.06);z-index:2}
/* ==== utilities.130.css ==== */
/* переключатель темы — иконка солнце/луна крутится при смене */
@keyframes themeSpin{from{transform:rotate(-45deg) scale(.6);opacity:0}to{transform:rotate(0) scale(1);opacity:1}}

.tb-icon[data-act="theme"] svg,.tb-icon svg{transition:transform var(--dur) var(--ease-spring)}

/* ============================================================ 5. ПАНЕЛЬ ЗАДАЧИ И МОДАЛЬНЫЕ ОКНА */
/* Оверлей и панель уже используют cubic-bezier — синхронизируем со шкалой */
.overlay{transition:opacity var(--dur) var(--ease-standard)}
/* ==== layout.032.css ==== */
#panel{transition:transform var(--dur-panel) var(--ease-spring)}

/* раздел 7 аудита: единственный из трёх примеров идеальной реализации (тост, карточка при отпускании, панель), где пружинная кривая ещё не применена — у тоста и карточки --ease-spring уже победил в каскаде, у панели всё ещё был --ease-out без перелёта */
#panel.show{transition:transform var(--dur-panel) var(--ease-spring)}
/* ==== components.095.css ==== */
/* Модальное окно: явный выход, а не мгновенное исчезновение.
   closeModal() навешивает .closing и снимает .show с задержкой — здесь его анимация. */
.modal-back{transition:opacity var(--dur) var(--ease-standard)}

#modalRoot.closing .modal-back{opacity:0}

#modalRoot.closing .modal{animation:none;opacity:0;transform:translateY(8px) scale(.97);transition:opacity var(--dur-fast) var(--ease-in-out),transform var(--dur-fast) var(--ease-in-out)}

.modal.closing{opacity:0;transform:translateY(8px) scale(.97);transition:opacity var(--dur-fast) var(--ease-in-out),transform var(--dur-fast) var(--ease-in-out)}
/* ==== layout.033.css ==== */
.modal-x,.panel-close{transition:background var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard),transform var(--dur-fast) var(--ease-snap)}

.modal-x:active,.panel-close:active{transform:scale(.88) rotate(90deg)}

.panel-complete{transition:background var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard),transform var(--dur-fast) var(--ease-snap)}

.panel-complete:active{transform:scale(.97)}
/* ==== components.096.css ==== */
/* Поля панели — плавное появление рамки при фокусе/наведении */
.field-btn,.field-input,.desc-area,.desc-rendered,.desc-empty,.form-input,.auth-in,.comment-input-wrap{
  transition:background var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur) var(--ease-standard);
}

/* ============================================================ 6. ВЫПАДАЮЩИЕ МЕНЮ */
@keyframes menuIn{from{opacity:0;transform:translateY(-4px) scale(.97)}to{opacity:1;transform:translateY(0) scale(1)}}

@keyframes menuOut{from{opacity:1;transform:translateY(0) scale(1)}to{opacity:0;transform:translateY(-4px) scale(.97)}}

.menu{animation:menuIn var(--dur-fast) var(--ease-out)}

.menu.closing{animation:menuOut var(--dur-instant) var(--ease-in-out) forwards}

.menu-item{transition:background var(--dur-instant) var(--ease-standard),color var(--dur-instant) var(--ease-standard)}

.menu-item svg{transition:color var(--dur-instant) var(--ease-standard)}

.menu-item .mtick{transition:transform var(--dur-fast) var(--ease-spring)}
/* ==== utilities.131.css ==== */
/* эмодзи/цвет-пикеры в модалках */
.emoji-pick,.swatch{transition:background var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard),transform var(--dur-fast) var(--ease-snap),box-shadow var(--dur-fast) var(--ease-standard)}

.emoji-pick:active,.swatch:active{transform:scale(.92)}
/* ==== components.097.css ==== */
/* --- 7. ТОСТЫ ------------------------------------------------- */
@keyframes toastOut{to{opacity:0;transform:translateY(10px) scale(.96)}}

.toast{animation:toastIn var(--dur-slow) var(--ease-spring)}

.toast.out{animation:toastOut var(--dur-fast) var(--ease-in-out) forwards}

.toast .undo{transition:opacity var(--dur-fast) var(--ease-standard)}

.toast .undo:hover{opacity:.75}

.toast .undo:focus-visible{outline:none;opacity:.75;text-decoration:underline}

/* ============================================================ 8. DRAG & DROP */
/* Карточка доски: приподнимается и слегка наклоняется в руке,
   плавно садится на место при отпускании — за счёт transition,
   который не мешает мгновенному репозиционированию во время drag. */
.card{transition:box-shadow var(--dur) var(--ease-out),border-color var(--dur-fast) var(--ease-standard),transform var(--dur) var(--ease-spring)}

.card.dragging{transition:opacity var(--dur-fast) var(--ease-standard),transform var(--dur-fast) var(--ease-standard);cursor:grabbing}
/* ==== features.037.css ==== */
.board-col{transition:border-color var(--dur-fast) var(--ease-standard),background var(--dur-fast) var(--ease-standard),box-shadow var(--dur) var(--ease-standard)}

.board-col.drag-over{transform:scale(1.008)}

.board-col.col-dragging{transition:opacity var(--dur-fast) var(--ease-standard)}

.board-col.col-drop{transition:box-shadow var(--dur-fast) var(--ease-standard)}
/* ==== utilities.132.css ==== */
.bc-caret{transition:transform var(--dur) var(--ease-standard),background var(--dur-fast) var(--ease-standard)}

/* Строки списка при перетаскивании (drag reorder) и колонки календаря */
.row-caret svg{transition:transform var(--dur-fast) var(--ease-standard)}

.cal-ev{transition:filter var(--dur-fast) var(--ease-standard),transform var(--dur-fast) var(--ease-snap),opacity var(--dur-fast) var(--ease-standard)}

.cal-ev:active{transform:scale(.97)}

.cal-cell{transition:background var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard)}

.cal-cell.cal-drop{transform:scale(1.01)}

/* Хронология: перетаскиваемая полоса и маркер вехи */
.tl-ms:not(.dragging){transition:filter var(--dur-fast) var(--ease-standard),left var(--dur) var(--ease-out)}

/* Массовые выделения — плавное появление галочки */
.row-sel{transition:opacity var(--dur-fast) var(--ease-standard),background var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard),transform var(--dur-fast) var(--ease-snap)}

.row-sel:active{transform:scale(.85)}

@keyframes bulkIn{from{opacity:0;transform:translate(-50%,12px)}to{opacity:1;transform:translate(-50%,0)}}

.bulk-bar{animation:bulkIn var(--dur-slow) var(--ease-spring)}
/* ==== components.098.css ==== */
.bulk-btn{transition:background var(--dur-fast) var(--ease-standard),transform var(--dur-fast) var(--ease-snap)}

.bulk-btn:active{transform:scale(.95)}
/* ==== utilities.133.css ==== */
/* ============================================================ 9. ПРОГРЕСС И ГРАФИКИ */
/* Полосы и кольца уже анимируют ширину/значение в JS — здесь единая кривая */
.bar-fill{transition:width var(--dur-slow) var(--ease-out)}

.pf-prog-fill,.wl-bar>div{transition:width var(--dur-slow) var(--ease-out)}

.ring-wrap circle{transition:stroke-dashoffset var(--dur-slow) var(--ease-out)}

/* --- 10. Скелетон/загрузка: мягкое дыхание вместо жёсткого моргания --- */
@keyframes softPulse{0%,100%{opacity:1}50%{opacity:.55}}

.tb-sync.sync .tb-sync-dot{animation:softPulse 1.1s var(--ease-in-out) infinite}

/* --- 11. Свитчер настроек --- */
.st-sw-slider{transition:background var(--dur) var(--ease-standard)}

.st-sw-slider:before{transition:transform var(--dur) var(--ease-spring)}

.st-switch:active .st-sw-slider:before{transform:scale(.9) translateX(var(--_x,0))}
/* ==== components.099.css ==== */
/* --- 12. Вкладки настроек и «дом» --- */
.st-tab{transition:color var(--dur-fast) var(--ease-standard),border-color var(--dur) var(--ease-standard)}
/* ==== utilities.134.css ==== */
.cal-mode{transition:background var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard)}

/* --- 13. Уважение к системным настройкам ------------------------
   Полное отключение уже объявлено глобально в базовом слое —
   здесь только гарантия, что новые анимации попадают под то же
   правило (селектор * в базовом слое их уже покрывает).         */

/* ============================================================
   АДАПТИВНОСТЬ ДЛЯ БОЛЬШИХ ЭКРАНОВ
   Три отдельных яруса раскладки поверх базового (до 1919px):
     Ярус A — 1920–2559px   большие мониторы Full HD/1440p
     Ярус B — 2560–3439px   2K/QHD и широкие мониторы 16:9/16:10
     Ярус C — 3440px+ или произвольная ширина с широким соотношением
              сторон (21:9, 32:9) — включает Ultrawide и Super Ultrawide
   Правки только про раскладку и метрику: сетки, ширины контейнеров,
   раскладка виджетов Главной, колонки отчётов. Разметка и логика
   не меняются — везде используются существующие узлы DOM, просто
   переставленные через CSS Grid areas и разные grid-column/span.
   ============================================================ */

/* ---------------------------------------------------------------
   ЯРУС A · 1920–2559px
   Больше воздуха по краям, чуть шире боковая панель и панель задачи,
   доска показывает больше колонок разом без изменения их состава.
   --------------------------------------------------------------- */
@media (min-width:1920px){
  :root{
    --gutter:40px;
    --sidebar-w:280px;
  }
  .home-wrap{max-width:1360px}
  .goals-wrap{max-width:1180px}
  .inbox-wrap{max-width:860px}
  .dash-wrap{gap:20px}
  .board-col{width:312px}
  .board-addcol{width:312px}
  #panel{width:min(860px,92vw)}
  .cal-cell{min-height:120px}
  .prof-grid{grid-template-columns:360px 1fr}
  /* Список задач — та же самая проблема, что уже решена рядом для
     Отчётов/Портфеля/Календаря, только для него не была замечена:
     .task-row строится через grid-template-columns:1fr 160px 130px...
     — фиксированные метаданные (срок/приоритет/статус/исполнитель)
     остаются узкими, а вся лишняя ширина монитора целиком уходит в
     ПЕРВУЮ колонку (название задачи). На 1920px это ещё терпимо, но
     сам список — не то же самое, что доска: доска на ширине выигрывает
     буквально (больше видимых колонок статусов), список — не выигрывает
     ничего, кроме версии знак увеличивающегося пустого пространства
     между названием и остальными полями строки. Читается он, по сути,
     построчно, как отчёт или портфель — та же категория, тот же приём:
     ограничить и центрировать, а не растягивать бесконечно. */
  .list-wrap{max-width:1440px;margin:0 auto}
}

/* ---------------------------------------------------------------
   ЯРУС B · 2560–3439px
   На такой ширине одноколоночные панели превращаются в настоящий
   дашборд: «Мои задачи» занимает высокую левую колонку, «Проекты»
   и «Люди» встают друг под другом справа — вместо того чтобы просто
   растягивать те же две колонки шире. Отчёты переходят на 6 карточек
   в ряд вместо 4, чтобы плитки не раздувались до полуметра шириной.
   --------------------------------------------------------------- */
@media (min-width:2560px){
  :root{
    --gutter:48px;
    --sidebar-w:304px;
  }

  /* Главная: левая колонка — задачи на всю высоту, справа — стопка
     из двух более узких виджетов. Порядок узлов в DOM не меняется,
     переставляем только через именованные области сетки. */
  .home-wrap{max-width:1720px}
  .home-grid{
    grid-template-columns:2fr 1fr;
    grid-template-rows:auto auto;
    grid-template-areas:"main side1" "main side2";
    align-items:start;
  }
  .home-grid>.widget.wide{grid-area:main}
  .home-grid>.widget:nth-child(2){grid-area:side1}
  .home-grid>.widget:nth-child(3){grid-area:side2}

  /* Отчёты: плитки метрик остаются 4 в ряд (ровно заполняют сетку),
     а донат-графики разворачиваются с 2 в ряд до 4 — на 2560px
     диаграмма шириной в пол-экрана только теряет читаемость. */
  .dash-wrap{gap:22px}
  .chart-card.half{grid-column:span 3}

  /* Цели: карточки целей выстраиваются в две колонки —
     при таком запасе ширины одна колонка выглядит потерянной. */
  .goals-wrap{
    max-width:1560px;display:grid;
    grid-template-columns:1fr 1fr;gap:16px;align-items:start;
  }
  .goals-wrap .goal-card{margin-bottom:0}

  .inbox-wrap{max-width:920px}
  .pf-wrap{max-width:2000px;margin:0 auto}
  .board-col{width:324px}
  .board-addcol{width:324px}
  #panel{width:min(900px,90vw)}
  .cal-cell{min-height:132px}
  .prof-grid{grid-template-columns:380px 1fr}
  .list-wrap{max-width:1600px;margin:0 auto}
}

/* ---------------------------------------------------------------
   ЯРУС C · Ultrawide (3440px+, либо широкое соотношение сторон —
   21:9 и 32:9 мониторы, которые не всегда доходят до 3440px по
   ширине при небольшой высоте, например 2560×1080).
   Раскладка Главной становится трёхколоночной в один ряд: задачи,
   проекты и люди читаются одновременно без прокрутки вниз.
   Контентные ленты (отчёты, портфель, календарь, список задач) получают
   верхнюю границу ширины и центрируются — иначе на 5120px строка
   станет нечитаемо длинной; список задач добавлен в эту же категорию
   в этой версии — он читается построчно, как отчёт, а не выигрывает
   от ширины, как доска. Доска остаётся на всю ширину: единственный
   экран, где больше горизонтали — это буквально больше видимых
   колонок статусов без прокрутки, не просто больше пустого места
   внутри уже существующих.
   --------------------------------------------------------------- */
@media (min-width:3440px), (min-width:2200px) and (min-aspect-ratio:2/1){
  :root{
    --gutter:56px;
    --sidebar-w:316px;
    --t-display:32px;
    --t-h1:23px;
  }

  .home-wrap{max-width:2080px}
  .home-grid{
    grid-template-columns:1.7fr 1fr 1fr;
    grid-template-rows:auto;
    grid-template-areas:"main side1 side2";
    gap:22px;
  }
  .home-grid>.widget.wide{grid-area:main}
  .home-grid>.widget:nth-child(2){grid-area:side1}
  .home-grid>.widget:nth-child(3){grid-area:side2}

  .dash-wrap{max-width:2400px;margin:0 auto;gap:24px}
  .chart-card.half{grid-column:span 3}

  .goals-wrap{max-width:1680px}

  .inbox-wrap{max-width:960px}
  .pf-wrap{max-width:2200px;margin:0 auto}
  .cal-wrap{max-width:2400px;margin:0 auto}

  .board-col{width:336px}
  .board-addcol{width:336px}
  #panel{width:min(940px,88vw)}
  .cal-cell{min-height:140px}
  .prof-grid{grid-template-columns:400px 1fr}
  .list-wrap{max-width:1800px;margin:0 auto}

  /* На супер-широких мониторах (32:9) даже с capped-контентом полезно
     чуть больше воздуха вокруг рабочей области, чтобы она не сливалась
     с краями окна на расстоянии вытянутой руки от центра. */
  .page-head,.view-toolbar{padding-left:var(--gutter);padding-right:var(--gutter)}
}

.m-fab{display:none}
/* ==== components.100.css ==== */
.m-tabbar{display:none}
/* ==== utilities.135.css ==== */
/* ============================================================
   МОБИЛЬНАЯ АДАПТИВНОСТЬ — переработка
   Базовый мобильный блок выше решал задачу «уместить десктоп
   в узкое окно». Этот слой меняет подход: на телефоне интерфейс
   строится по мобильным паттернам — нижние шиты вместо боковых
   панелей, строки-карточки вместо урезанной таблицы, липкая
   панель основного действия, зоны нажатия от 44px.
   ============================================================ */

/* --- 1. Реальная высота окна ---------------------------------
   100vh на мобильных браузерах считается без адресной строки:
   низ интерфейса уезжает под неё. dvh учитывает динамический UI. */
@supports (height:100dvh){
  @media(max-width:768px){
    #app{height:100dvh}
    #panel{height:100dvh}
    #sidebar{height:100dvh}
    /* Ниже — пробелы в той же самой обработке, найденные аудитом.
       #app уже переводился на dvh, а вложенная в него .workspace
       продолжала считать высоту в 100vh: контейнер по фактической
       высоте окна, содержимое — по высоте без адресной строки, и
       низ рабочей области уезжал под неё.
       Модальные окна ограничивались по 100vh, то есть на телефоне
       окно могло оказаться выше видимой части, и первой за нижний
       край уходила строка кнопок — «Сохранить» и «Отмена».
       Лента времени считала высоту так же.
       Правила стоят внутри существующего @supports: там, где dvh не
       поддерживается, всё остаётся как было. */
    .workspace{height:100dvh}
    .modal{max-height:calc(100dvh - 40px)}
    .tl2-wrap{height:calc(100dvh - var(--topbar-h) - 118px)}
  }
}

@media(max-width:768px){

  /* --- 2. Зоны нажатия ---------------------------------------
     Пальцем нужно 44px, курсором хватало 26–30px.              */
  .tb-icon,.tb-burger{width:42px;height:42px}
  .side-collapse,.modal-x,.panel-close{width:42px;height:42px}
  .nav-item,.proj-item{padding:11px 12px}
  .menu-item{padding:12px 12px;font-size:var(--t-h3)}
  .task-check,.card-check,.mini-check{width:24px;height:24px}
  .sh-actions button,.bc-menu{width:36px;height:36px}
  /* высота задаётся через min-height: паддинги в разных кнопках
     разные, а палец должен попадать одинаково уверенно везде */
  /* Ступени размеров из дизайн-системы задают фиксированную высоту;
     на телефоне она перебивается минимальной, потому что палец —
     не курсор: 36px хватает для наведения и не хватает для попадания. */
  .btn{padding:10px 15px;min-height:44px;height:auto}
  .btn-icon-only{width:44px;min-width:44px;padding:0}
  .add-section-input,.rename-inp{min-height:44px;height:auto}
  .tb-create-caret{width:38px}
  .btn-sm{padding:9px 13px;min-height:40px;height:auto}
  .chip{padding:8px 13px;min-height:40px;height:auto}
  .tb-create{height:42px}
  .btn-create{min-height:44px}
  .nav-label .add{width:38px;height:38px}
  .avatar-add{width:36px;height:36px}
  /* мелкие внутристрочные элементы управления получают невидимый
     запас нажатия вокруг себя, не меняя визуальный размер */
  .row-sel,.row-caret{position:relative}
  .row-sel::after,.row-caret::after{content:"";position:absolute;inset:-13px}
  .home-tab,.tab,.st-tab{padding-top:11px;padding-bottom:13px}
  .swatch{width:38px;height:38px}
  .emoji-pick{width:46px;height:46px}
  /* мелкие иконки-удаления получают невидимый запас вокруг */
  .sv-del,.mh-x,.sub-del,.tag-x,.dep-del{position:relative}
  .sv-del::after,.mh-x::after,.sub-del::after,.tag-x::after,.dep-del::after{
    content:"";position:absolute;inset:-11px;
  }
  /* на тач-устройствах кнопки удаления не должны быть скрыты по hover */
  .sv-del{opacity:1}

  /* --- 3. Список задач: строка-карточка ----------------------
     Раньше на телефоне таблица урезалась до 2 колонок и
     исполнитель, приоритет, статус и срок просто исчезали.
     Теперь строка превращается в двухстрочную карточку:
     название сверху, метаданные компактной лентой снизу —
     видно всё то же, что на десктопе.                          */
  .list-colhead{display:none}
  .task-row{
    display:flex!important;flex-wrap:wrap;align-items:center;gap:6px 8px;
    grid-template-columns:none!important;
    padding:12px 14px;min-height:0;margin:0 0 6px;
    background:var(--surface);border:1px solid var(--line);
    border-radius:var(--r-md);box-shadow:var(--shadow-xs);
  }
  [data-theme="dark"] .task-row{background:var(--surface-2)}
  .task-row>*{display:flex!important}
  .task-row .task-main{flex:1 1 100%;min-width:0;align-items:center}
  .task-row .task-name{white-space:normal;font-size:var(--t-h3);line-height:1.35}
  /* метаданные — вторая строка, каждая ячейка как чип */
  .task-row>*:not(.task-main){
    flex:0 0 auto;font-size:var(--t-sm);
  }
  .task-row .cell-empty{display:none!important}
  .task-row .row-caret,.task-row .row-sel{flex:0 0 auto}
  .task-row:hover{transform:none;box-shadow:var(--shadow-xs)}
  .add-task-row{border-radius:var(--r-md);margin-bottom:6px}
  /* --- Карточки: компактность вместо десктопных полей ---------
     Карточки сохраняли отступ 20/22px с большого экрана. На
     телефоне это 44 пикселя полей по горизонтали — при ширине
     экрана 360 и отступах страницы от них остаётся меньше 300
     пикселей на само содержимое, то есть примерно шестая часть
     экрана уходит на пустоту внутри рамок. Поля ужимаются,
     содержимое — нет. */
  .widget,.chart-card{padding:14px 15px;border-radius:var(--r-md)}
  .person-card{padding:15px 11px}
  .stat-card{padding:13px 14px}
  .ov-stat{padding:11px 12px}
  .card{padding:11px 12px}
  /* Строки-карточки со списком действий: на узком экране кнопки
     переходят на свою строку, а не сдавливают название до
     нечитаемого огрызка. */
  .arc-row,.trash-row{flex-wrap:wrap;row-gap:10px}
  .arc-main,.trash-main{flex:1 1 100%}
  .arc-row>.btn,.trash-row>.btn{flex:1 1 auto}

  /* --- 4. Доска: колонки с прилипанием ----------------------- */
  .board-wrap{
    scroll-snap-type:x mandatory;
    scroll-padding-left:12px;
    padding-bottom:88px;
  }
  .board-col{scroll-snap-align:start;min-width:84vw;max-height:none}
  .board-addcol{scroll-snap-align:start;min-width:70vw}

  /* --- 5. Панель задачи как нижний шит -----------------------
     Слайд справа — десктопный жест. На телефоне естественнее
     шит снизу: до ручки дотягивается большой палец, а не мизинец.
     Класс .show уже ставится в JS, меняем только ось движения.  */
  #panel{
    top:auto;bottom:0;right:0;left:0;
    width:100vw!important;max-width:100vw!important;
    height:94dvh;max-height:94dvh;
    border-radius:var(--r-xl) var(--r-xl) 0 0;
    transform:translateY(100%);
    box-shadow:0 -1px 0 var(--line),0 -24px 60px -12px rgba(0,0,0,.5);
  }
  #panel.show{transform:translateY(0)}
  /* ручка захвата — визуальный намёк, что шит тянется вниз */
  .panel-top{position:relative;padding-top:20px}
  .panel-top::before{
    content:"";position:absolute;top:8px;left:50%;transform:translateX(-50%);
    width:38px;height:4px;border-radius:var(--r-xs);background:var(--line-3);
  }
  .panel-body{padding:20px 18px calc(40px + env(safe-area-inset-bottom))}
  .panel-name{font-size:var(--t-lg);margin-bottom:18px}
  /* поля панели в одну колонку — подпись над значением */
  .field-grid{grid-template-columns:1fr!important;gap:2px}
  .field-lbl{padding:8px 0 2px}
  .field-btn{margin-left:0}

  /* --- 6. Модальные окна как нижний шит --------------------- */
  #modalRoot{padding:0;align-items:flex-end}
  .modal{
    width:100%;max-width:100%;
    border-radius:var(--r-xl) var(--r-xl) 0 0;
    max-height:92dvh;display:flex;flex-direction:column;
    animation:sheetIn var(--dur-slow) var(--ease-out);
  }
  @keyframes sheetIn{from{transform:translateY(100%)}to{transform:translateY(0)}}
  #modalRoot.closing .modal,.modal.closing{
    transform:translateY(100%);opacity:1;
    transition:transform var(--dur-fast) var(--ease-in-out);
  }
  .modal-head{padding-top:20px;position:relative;flex:none}
  .modal-head::before{
    content:"";position:absolute;top:8px;left:50%;transform:translateX(-50%);
    width:38px;height:4px;border-radius:var(--r-xs);background:var(--line-3);
  }
  .modal-body{overflow-y:auto;-webkit-overflow-scrolling:touch}
  .modal-foot{
    flex:none;position:sticky;bottom:0;
    padding-bottom:calc(14px + env(safe-area-inset-bottom));
  }
  .modal-foot .btn{flex:1;justify-content:center}
  .form-input,.field-input,.auth-in{font-size:var(--t-h2)}  /* 16px = iOS не зумит при фокусе */

  /* --- 7. Выпадающие меню как шит --------------------------- */
  .menu{
    left:0!important;right:0!important;top:auto!important;bottom:0!important;
    width:100%;min-width:0;max-height:70dvh;overflow-y:auto;
    border-radius:var(--r-xl) var(--r-xl) 0 0;
    padding:10px 10px calc(14px + env(safe-area-inset-bottom));
    animation:sheetIn var(--dur-fast) var(--ease-out);
  }
  .menu.closing{animation:none;transform:translateY(100%);transition:transform var(--dur-instant) var(--ease-in-out)}

  /* --- 8. Панель фильтров: горизонтальная лента ------------- */
  .view-toolbar{
    flex-wrap:nowrap!important;overflow-x:auto;
    -webkit-overflow-scrolling:touch;scrollbar-width:none;
    row-gap:0!important;padding-top:10px;padding-bottom:10px;
  }
  .view-toolbar::-webkit-scrollbar{display:none}
  .view-toolbar>*{flex:0 0 auto}
  .toolbar-spacer{display:none}
  /* мягкое затухание у правого края — намёк, что лента скроллится */
  .tabs,.view-toolbar,.st-tabs{
    mask-image:linear-gradient(to right,#000 calc(100% - 24px),transparent);
    -webkit-mask-image:linear-gradient(to right,#000 calc(100% - 24px),transparent);
  }

  /* --- 9. Липкая панель основного действия -------------------
     На телефоне «Создать» в топбаре попадает под большой палец
     только с перехватом. Дублируем действие внизу — там, где
     палец находится в покое.                                   */
  .content-scroll{padding-bottom:calc(130px + env(safe-area-inset-bottom))}
  .m-fab{display:flex;
    position:fixed;right:16px;
    bottom:calc(74px + env(safe-area-inset-bottom));
    z-index:55;display:flex;align-items:center;gap:8px;
    height:52px;padding:0 20px 0 17px;border-radius:var(--r-pill);
    background:var(--accent);color:var(--accent-fg);
    font-weight:600;font-size:var(--t-h3);border:0;cursor:pointer;
    box-shadow:var(--shadow-lg),inset 0 1px 0 rgba(255,255,255,.2);
    transition:transform var(--dur-fast) var(--ease-snap);
  }
  .m-fab:active{transform:scale(.94)}
  /* прячем, когда открыт шит/панель/модалка, чтобы не перекрывал */
  #panel.show ~ .m-fab,body:has(#modalRoot.show) .m-fab,body:has(#panel.show) .m-fab{
    opacity:0;pointer-events:none;transform:translateY(12px);
  }

  /* --- 9б. Нижняя панель навигации ----------------------------
     Раньше даже «Мои задачи» и «Входящие» — самые частые места
     назначения — требовали два касания (открыть гамбургер, затем
     выбрать пункт). Настоящее мобильное приложение держит несколько
     главных пунктов снизу, всегда на расстоянии одного касания
     большого пальца; гамбургер остаётся для всего остального. */
  .m-tabbar{
    display:flex;position:fixed;left:0;right:0;bottom:0;z-index:56;
    height:calc(58px + env(safe-area-inset-bottom));
    padding-bottom:env(safe-area-inset-bottom);
    background:var(--canvas);border-top:1px solid var(--line-2);
    box-shadow:0 -2px 12px rgba(0,0,0,.05);
  }
  [data-theme="dark"] .m-tabbar{box-shadow:none}
  #panel.show ~ .m-tabbar,body:has(#modalRoot.show) .m-tabbar,body:has(#panel.show) .m-tabbar{
    opacity:0;pointer-events:none;transform:translateY(12px);
  }
  .m-tab{
    flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
    min-height:44px;color:var(--faint);position:relative;transition:color var(--dur-instant);
  }
  .m-tab svg{width:20px;height:20px}
  .m-tab-lbl{font-size:var(--t-micro);font-weight:600;letter-spacing:-.01em}
  .m-tab.active{color:var(--accent)}
  .m-tab:active{opacity:.6}
  .m-tab-badge{position:absolute;top:2px;right:calc(50% - 14px);width:7px;height:7px;border-radius:50%;background:var(--danger);border:1.5px solid var(--canvas)}

  /* --- 10. Прочее ------------------------------------------- */
  #topbar{padding-top:env(safe-area-inset-top);height:calc(var(--topbar-h) + env(safe-area-inset-top))}
  .bulk-bar{left:12px;right:12px;transform:none;width:auto;justify-content:center;flex-wrap:wrap}
  @keyframes bulkIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}
  .home-greet{font-size:26px}
  .home-kpis{gap:8px}
  .home-kpi{padding:7px 13px 7px 9px}
  .goal-card{flex-direction:column;align-items:flex-start;gap:16px}
  .goal-card .ring-wrap{align-self:center}
  .empty-state{padding:48px 16px}
  .toast{left:12px;right:12px;justify-content:center}
  .print-status{left:12px;right:12px;transform:none;max-width:none;justify-content:center}
  /* убираем hover-эффекты приподнимания там, где нет курсора */
  .card:hover,.widget:hover,.stat-card:hover,.chart-card:hover,
  .goal-card:hover,.person-card:hover,.file-card:hover,.home-kpi:hover{transform:none}
}

/* --- 11. Тач-устройства любого размера ------------------------
   Планшет в ландшафте шире 768px, но курсора там тоже нет.     */
@media (hover:none) and (pointer:coarse){
  .card:hover,.widget:hover,.home-kpi:hover,.avatar-stack .avatar:hover{transform:none}
  .sv-del,.dep-del,.attach-dl{opacity:1}
  .task-row{min-height:52px}
  .tb-icon{width:42px;height:42px}
}

/* --- 12. Очень узкие экраны (до 360px) ----------------------- */
@media(max-width:360px){
  :root{--gutter:12px}
  .home-greet{font-size:var(--t-h1)}
  .ph-title{font-size:var(--t-h1)}
  .tb-create span:not(.tb-create-ic){display:none}
  .tb-create{padding:0 10px}
  .m-fab span{display:none}
  .m-fab{padding:0;width:52px;justify-content:center}
}
/* ==== features.038.css ==== */
/* ============================================================
   ПЛОТНЫЙ РЕЖИМ (Ctrl/⌘+.) — реальные изменения метрики, а не
   просто атрибут. Раньше переключатель в настройках сохранял
   значение, которое нигде не читалось. Плотность нужна несколько
   раз в день в зависимости от задачи, а не раз и навсегда — поэтому
   горячая клавиша, а не только тумблер в настройках.
   ============================================================ */
[data-density="compact"] .task-row{min-height:34px;padding-top:2px;padding-bottom:2px}

[data-density="compact"] .task-name{font-size:var(--t-body)}
/* ==== components.101.css ==== */
[data-density="compact"] .card{padding:8px 10px}

[data-density="compact"] .card-title{font-size:var(--t-body)}

[data-density="compact"] .card-top{margin-bottom:4px}

[data-density="compact"] .card-meta{margin-bottom:6px;gap:4px}
/* ==== layout.034.css ==== */
[data-density="compact"] .nav-item,[data-density="compact"] .proj-item{padding:5px 10px;font-size:var(--t-body)}
/* ==== utilities.136.css ==== */
[data-density="compact"] .list-wrap{padding-top:4px}

[data-density="compact"] .section-block{margin-top:8px}

[data-density="compact"] .section-head{padding:8px 12px 4px}
/* ==== features.039.css ==== */
[data-density="compact"] .board-wrap{padding-top:12px}
/* ==== utilities.137.css ==== */
[data-density="compact"] .bc-body{gap:6px}

[data-density="compact"] .inbox-item{padding:9px 14px}
/* ==== components.102.css ==== */
[data-density="compact"] .goal-card{padding:14px 16px;margin-bottom:8px}
/* ==== utilities.138.css ==== */
[data-density="compact"] .pf-row{padding:10px 20px}
/* ==== features.040.css ==== */
/* ============================================================
   КОМАНДНАЯ ПАЛИТРА
   ============================================================ */
.cmdk-overlay{position:fixed;inset:0;z-index:95;background:rgba(15,16,32,.4);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);display:flex;justify-content:center;padding-top:12vh;animation:cmdkFade var(--dur-fast,150ms) ease}

[data-theme="dark"] .cmdk-overlay{background:rgba(0,0,0,.6)}

.cmdk-overlay.closing{animation:cmdkFadeOut var(--dur-fast,150ms) ease forwards}

@keyframes cmdkFade{from{opacity:0}to{opacity:1}}

@keyframes cmdkFadeOut{to{opacity:0}}

.cmdk-box{
  width:min(600px,92vw);max-height:64vh;background:var(--raised);border:1px solid var(--line);
  border-radius:var(--r-xl);box-shadow:var(--shadow-lg),inset 0 1px 0 var(--edge-hi);
  display:flex;flex-direction:column;overflow:hidden;height:min-content;
  animation:cmdkPop var(--dur-slow,250ms) cubic-bezier(.16,1,.3,1);
}

@keyframes cmdkPop{from{opacity:0;transform:translateY(-10px) scale(.98)}to{opacity:1;transform:none}}
/* ==== components.103.css ==== */
.cmdk-inputwrap{display:flex;align-items:center;gap:10px;padding:14px 18px;border-bottom:1px solid var(--line);flex-shrink:0;color:var(--faint)}

.cmdk-input{flex:1;border:0;background:transparent;outline:none;font-size:var(--t-h3);color:var(--ink);font-family:inherit}

.cmdk-input::placeholder{color:var(--faint)}
/* ==== features.041.css ==== */
.cmdk-list{overflow-y:auto;padding:6px;flex:1;min-height:0}

.cmdk-sec{font-size:var(--t-xs);font-weight:600;color:var(--faint);padding:10px 10px 4px}

.cmdk-item{display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:var(--r-sm);cursor:pointer;font-size:var(--t-body);color:var(--ink-2)}

.cmdk-item.active{background:var(--accent-soft);color:var(--accent-700)}

[data-theme="dark"] .cmdk-item.active{color:var(--accent-600)}

.cmdk-ic{display:flex;color:var(--faint);flex-shrink:0}

.cmdk-item.active .cmdk-ic{color:currentColor}

.cmdk-emoji{flex-shrink:0}

.cmdk-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.cmdk-mark{background:var(--accent-soft);color:var(--accent-700);border-radius:2px;padding:0 1px;font-weight:700}

.cmdk-sub{font-size:var(--t-xs);color:var(--faint);flex-shrink:0}

.cmdk-hint{font-family:var(--mono);font-size:var(--t-micro);color:var(--faint);background:var(--surface-3);padding:1px 6px;border-radius:var(--r-xs);flex-shrink:0}

.cmdk-empty{padding:28px 10px;text-align:center;color:var(--faint);font-size:var(--t-body)}

.cmdk-foot{display:flex;gap:16px;padding:9px 16px;border-top:1px solid var(--line);background:var(--surface-2);font-size:var(--t-xs);color:var(--faint);flex-shrink:0}

.cmdk-kk{font-family:var(--mono);background:var(--surface-3);padding:1px 6px;border-radius:var(--r-xs);margin-right:5px}

/* ============================================================
   АКТИВНАЯ СТРОКА СПИСКА — подсветка при навигации с клавиатуры
   ============================================================ */
.task-row.row-focus{
  background:var(--surface);box-shadow:0 0 0 1.5px var(--accent-line),var(--shadow-sm),inset 0 1px 0 var(--edge-hi);
  border-bottom-color:transparent;
}

[data-theme="dark"] .task-row.row-focus{background:var(--surface-2)}
/* ==== utilities.139.css ==== */
/* ============================================================
   РЕЖИМ ФОКУСА
   ============================================================ */
.focus-overlay{
  position:fixed;inset:0;z-index:96;background:var(--canvas);
  display:flex;align-items:center;justify-content:center;padding:40px 20px;
  animation:focusIn var(--dur-slow,250ms) var(--ease-out,ease);
}

[data-theme="dark"] .focus-overlay{background:var(--chrome-2)}

@keyframes focusIn{from{opacity:0}to{opacity:1}}

.focus-overlay.closing{animation:focusOut var(--dur-fast,150ms) ease forwards}

@keyframes focusOut{to{opacity:0}}

.focus-exit{position:fixed;top:22px;right:26px;width:40px;height:40px;border-radius:var(--r-md);display:flex;align-items:center;justify-content:center;color:var(--muted);background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-sm);transition:var(--dur-fast)}

.focus-exit:hover{background:var(--surface-3);color:var(--ink)}

.focus-box{width:min(560px,92vw);text-align:center;display:flex;flex-direction:column;align-items:center}

.focus-timer{display:flex;align-items:center;gap:14px;margin-bottom:28px}

.focus-timer span{font-family:var(--mono);font-size:36px;font-weight:600;letter-spacing:-.02em;color:var(--ink);font-variant-numeric:tabular-nums}
/* ==== components.104.css ==== */
.focus-timer-btn{width:40px;height:40px;border-radius:50%;background:var(--accent);color:var(--accent-fg);display:flex;align-items:center;justify-content:center;box-shadow:var(--shadow-sm);transition:var(--dur-fast)}

.focus-timer-btn:hover{background:var(--accent-600)}
/* ==== utilities.140.css ==== */
.focus-eyebrow{font-size:var(--t-xs);font-weight:500;color:var(--faint);margin-bottom:10px}

.focus-title{font-size:26px;font-weight:700;letter-spacing:-.03em;color:var(--ink);line-height:1.3;margin-bottom:14px}

.focus-desc{font-size:var(--t-h3);line-height:1.6;color:var(--muted);max-width:52ch;margin-bottom:20px}

.focus-subs{width:100%;max-width:400px;text-align:left;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);padding:14px 16px;margin-bottom:24px;box-shadow:var(--shadow-sm)}

.focus-subs-head{font-size:var(--t-xs);font-weight:600;color:var(--faint);margin-bottom:8px}

.focus-sub{display:flex;align-items:center;gap:10px;padding:6px 0;font-size:var(--t-body);color:var(--ink-2)}

.focus-sub.done{color:var(--faint);text-decoration:line-through}

.focus-sub-check{width:17px;height:17px;border-radius:50%;border:1.5px solid var(--line-3);flex-shrink:0;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:var(--dur-fast)}

.focus-sub-check svg{opacity:0;color:var(--on-solid)}

.focus-sub.done .focus-sub-check{background:var(--ok);border-color:var(--ok)}

.focus-sub.done .focus-sub-check svg{opacity:1}

.focus-done{padding:10px 22px}
/* ==== layout.035.css ==== */
.panel-focus-btn{margin-right:auto}
/* ==== utilities.141.css ==== */
/* ============================================================
   ЗАЩИЩЁННЫЕ РАЗДЕЛЫ («Крит») и обязательная проверка
   ============================================================ */
.sec-lock{color:var(--muted);background:var(--surface-3);margin-left:4px}

[data-theme="dark"] .sec-lock{color:var(--muted)}
/* ==== features.042.css ==== */
.board-col.locked-col{box-shadow:inset 0 0 0 1.5px var(--warn-line)}

.board-col.locked-col .bc-head{background:var(--warn-soft);border-radius:var(--r-lg) var(--r-lg) 0 0}
/* ==== utilities.142.css ==== */
/* ============================================================
   ГОЛОСОВАНИЕ В ЗАДАЧЕ
   ============================================================ */
.poll-empty{
  display:flex;align-items:center;gap:9px;padding:12px 14px;
  border:1px dashed var(--line-3);border-radius:var(--r-md);
  color:var(--faint);font-size:var(--t-body);cursor:pointer;transition:var(--dur-fast);
}

.poll-empty:hover{border-color:var(--accent);color:var(--accent-700);background:var(--accent-soft-2)}

[data-theme="dark"] .poll-empty:hover{color:var(--accent-600)}

.poll-box{border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden;background:var(--surface-2)}

.poll-box.closed{opacity:.86}

.poll-head{display:flex;align-items:center;gap:9px;padding:11px 13px;border-bottom:1px solid var(--line)}

.poll-q{font-size:var(--t-body);font-weight:600;color:var(--ink);flex:1;min-width:0}
/* ==== components.105.css ==== */
.poll-badge{font-size:var(--t-micro);font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);background:var(--surface-3);padding:2px 8px;border-radius:var(--r-pill);flex-shrink:0}
/* ==== utilities.143.css ==== */
.poll-act{width:26px;height:26px;border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;color:var(--faint);flex-shrink:0;transition:var(--dur-instant)}

.poll-act:hover{background:var(--surface-3);color:var(--ink)}

.poll-opt{position:relative;border-bottom:1px solid var(--line-2);cursor:pointer;overflow:hidden;transition:background var(--dur-instant)}

.poll-opt:last-of-type{border-bottom:none}

.poll-opt:hover:not(.closed){background:var(--surface-3)}

.poll-opt.closed{cursor:default}

.poll-bar{position:absolute;left:0;top:0;bottom:0;background:var(--accent-soft);transition:width var(--dur-slow,var(--dur-slow)) var(--ease-out,ease)}

.poll-opt.mine .poll-bar{background:var(--accent-soft);box-shadow:inset -2px 0 0 var(--accent)}

.poll-opt-body{position:relative;display:flex;align-items:center;gap:10px;padding:10px 13px}

.poll-radio{
  width:17px;height:17px;border-radius:50%;border:1.5px solid var(--line-3);
  flex-shrink:0;display:flex;align-items:center;justify-content:center;color:var(--on-solid);transition:var(--dur-fast);
}

.poll-opt.mine .poll-radio{background:var(--accent);border-color:var(--accent)}

.poll-text{flex:1;min-width:0;font-size:var(--t-body);color:var(--ink-2)}

.poll-opt.mine .poll-text{color:var(--ink);font-weight:500}

.poll-avs{display:flex;flex-shrink:0}
/* ==== components.106.css ==== */
.poll-avs .avatar{margin-left:-6px;border:2px solid var(--surface-2)}

.poll-avs .avatar:first-child{margin-left:0}
/* ==== utilities.144.css ==== */
.poll-num{font-family:var(--mono);font-size:var(--t-xs);color:var(--muted);flex-shrink:0;min-width:56px;text-align:right;font-variant-numeric:tabular-nums}

.poll-foot{padding:9px 13px;font-size:var(--t-xs);color:var(--faint);border-top:1px solid var(--line-2);background:var(--surface)}

[data-theme="dark"] .poll-foot{background:var(--surface)}

/* ============================================================
   ГРУППЫ И ПОДГРУППЫ В САЙДБАРЕ
   ============================================================ */
.grp{margin-bottom:2px}

.grp-head{
  display:flex;align-items:center;gap:7px;padding:6px 8px;border-radius:var(--r-sm);
  cursor:pointer;user-select:none;color:var(--ink-2);font-size:var(--t-sm);font-weight:600;
  transition:background var(--dur-instant),color var(--dur-instant);
}

.grp-head:hover{background:var(--surface-3);color:var(--ink)}

.grp-head.drag-over,.subgrp-head.drag-over{background:var(--accent-soft);color:var(--accent-700);box-shadow:inset 0 0 0 1.5px var(--accent-line)}

.proj-item.dragging{opacity:.4}

.proj-item{cursor:grab}

.proj-item:active{cursor:grabbing}

.grp-caret{display:flex;color:var(--faint);flex-shrink:0;transition:transform var(--dur,var(--dur)) var(--ease-standard,ease)}

.grp.collapsed>.grp-head .grp-caret,.subgrp.collapsed>.subgrp-head .grp-caret{transform:rotate(-90deg)}

.grp-emoji{font-size:var(--t-body);flex-shrink:0;line-height:1}

.grp-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.grp-count{
  font-family:var(--mono);font-size:var(--t-micro);color:var(--muted);background:var(--surface-3);
  padding:1px 6px;border-radius:var(--r-pill);flex-shrink:0;font-variant-numeric:tabular-nums;
}
/* ==== components.107.css ==== */
.grp-menu{
  width:22px;height:22px;border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;
  color:var(--faint);flex-shrink:0;opacity:0;transition:var(--dur-instant);
}

.grp-head:hover .grp-menu,.grp-menu:focus-visible{opacity:1}

.grp-menu:hover{background:var(--surface);color:var(--ink)}

.grp-menu:focus-visible{outline:none;box-shadow:var(--ring)}
/* ==== utilities.145.css ==== */
/* Быстрое действие на строке проекта — тот же приём, что и у "..."
   заголовка группы выше: скрыто по умолчанию, чтобы не шуметь в
   списке из полусотни проектов, и появляется по наведению или по
   клавиатурному фокусу, а не только по мыши. */
.proj-item{position:relative}

.proj-item-quick{
  width:20px;height:20px;border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;
  color:var(--faint);flex-shrink:0;margin-left:auto;opacity:0;transition:var(--dur-instant);
}

.proj-item:hover .proj-item-quick,.proj-item-quick:focus-visible{opacity:1}

.proj-item-quick:hover{background:var(--surface);color:var(--ink)}

.proj-item-quick:focus-visible{outline:none;box-shadow:var(--ring)}

.collapsed .proj-item-quick{display:none}

.grp-body{padding-left:9px;overflow:hidden}

.grp.collapsed>.grp-body{display:none}

.subgrp{margin:1px 0}

.subgrp-head{
  display:flex;align-items:center;gap:6px;padding:5px 8px;border-radius:var(--r-xs);
  cursor:pointer;user-select:none;color:var(--muted);font-size:var(--t-sm);font-weight:500;
  transition:background var(--dur-instant),color var(--dur-instant);
}

.subgrp-head:hover{background:var(--surface-3);color:var(--ink-2)}

.subgrp-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.subgrp-body{padding-left:10px;border-left:1px solid var(--line);margin-left:7px}

.subgrp.collapsed>.subgrp-body{display:none}

.grp-empty{font-size:var(--t-xs);color:var(--faint);padding:5px 10px;font-style:italic}

.collapsed .grp-head,.collapsed .subgrp-head,.collapsed .grp-empty{display:none}

.collapsed .grp-body,.collapsed .subgrp-body{padding-left:0;border-left:none;margin-left:0}

/* ============================================================
   КОНСТРУКТОР АВТОМАТИЗАЦИЙ
   ============================================================ */
.auto-overlay{
  position:fixed;inset:0;z-index:97;background:rgba(15,16,32,.4);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);
  display:flex;align-items:center;justify-content:center;padding:32px;
  animation:cmdkFade var(--dur-fast,150ms) ease;
}

[data-theme="dark"] .auto-overlay{background:rgba(0,0,0,.6)}

.auto-overlay.closing{animation:cmdkFadeOut var(--dur-fast,150ms) ease forwards}

.auto-box{
  width:min(880px,94vw);max-height:88vh;background:var(--raised);border:1px solid var(--line);
  border-radius:var(--r-xl);box-shadow:var(--shadow-lg),inset 0 1px 0 var(--edge-hi);
  display:flex;flex-direction:column;overflow:hidden;
  animation:cmdkPop var(--dur-slow,250ms) cubic-bezier(.16,1,.3,1);
}

.auto-head{display:flex;align-items:flex-start;gap:14px;padding:20px 22px 16px;border-bottom:1px solid var(--line);flex-shrink:0}

.auto-head-t{flex:1;min-width:0;font-size:var(--t-lg);font-weight:700;letter-spacing:-.02em;color:var(--ink);display:flex;flex-direction:column;gap:3px}

.auto-head-eyebrow{font-size:var(--t-xs);font-weight:500;color:var(--faint)}
/* ==== components.108.css ==== */
.auto-name-input{border:0;background:transparent;font-size:var(--t-lg);font-weight:700;letter-spacing:-.02em;color:var(--ink);padding:2px 0;width:100%;outline:none;border-radius:var(--r-xs)}

.auto-name-input:focus{background:var(--surface-2);padding:2px 8px;margin-left:-8px}
/* ==== utilities.146.css ==== */
.auto-head-actions{display:flex;align-items:center;gap:10px;flex-shrink:0}

.auto-close{width:32px;height:32px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;color:var(--muted);transition:var(--dur-fast)}

.auto-close:hover{background:var(--surface-3);color:var(--ink)}

.auto-switch{position:relative;display:inline-block;width:36px;height:21px;flex-shrink:0}
/* ==== components.109.css ==== */
.auto-switch input:focus-visible+.auto-sw-slider{box-shadow:var(--ring)}

.auto-switch input:disabled+.auto-sw-slider{opacity:.45;cursor:not-allowed}

.auto-switch input{opacity:0;width:0;height:0}
/* ==== utilities.147.css ==== */
.auto-sw-slider{position:absolute;inset:0;background:var(--line-3);border-radius:var(--r-xl);transition:var(--dur);cursor:pointer}

.auto-sw-slider:before{content:'';position:absolute;width:15px;height:15px;left:3px;top:3px;background:#fff;border-radius:50%;transition:var(--dur);box-shadow:0 1px 3px rgba(0,0,0,.25)}
/* ==== components.110.css ==== */
.auto-switch input:checked+.auto-sw-slider{background:var(--accent)}

.auto-switch input:checked+.auto-sw-slider:before{transform:translateX(15px)}
/* ==== utilities.148.css ==== */
.auto-hub-body{overflow-y:auto;padding:14px 18px 20px;flex:1}

.auto-row{display:flex;align-items:center;gap:14px;padding:13px 12px;border-radius:var(--r-lg);transition:background var(--dur-instant)}

.auto-row:hover{background:var(--surface-2)}

.auto-row-off{opacity:.55}

.auto-row-body{flex:1;min-width:0;cursor:pointer}

.auto-row-name{font-size:var(--t-body);font-weight:600;color:var(--ink);display:flex;align-items:center;gap:8px;margin-bottom:4px}

.auto-tag{font-size:var(--t-micro);font-weight:600;text-transform:uppercase;letter-spacing:.05em;padding:1px 7px;border-radius:var(--r-pill)}

.auto-tag-global{background:var(--accent-soft);color:var(--accent-700)}

[data-theme="dark"] .auto-tag-global{color:var(--accent-600)}

.auto-row-meta{display:flex;align-items:center;gap:8px;flex-wrap:wrap}

.auto-chip{display:inline-flex;align-items:center;gap:5px;font-size:var(--t-xs);color:var(--muted);background:var(--surface-3);padding:2px 9px;border-radius:var(--r-pill)}

.auto-lastrun{font-size:var(--t-xs);color:var(--faint)}

.auto-row-actions{display:flex;gap:2px;flex-shrink:0}
/* ==== components.111.css ==== */
.auto-icbtn{width:30px;height:30px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;color:var(--faint);transition:var(--dur-instant)}

.auto-icbtn.sm{width:24px;height:24px}

.auto-icbtn:hover{background:var(--surface-3);color:var(--ink)}

.auto-icbtn.danger:hover{background:var(--danger-soft);color:var(--danger)}

.auto-icbtn:focus-visible{outline:none;box-shadow:var(--ring)}

.auto-icbtn:disabled,.auto-icbtn[disabled]{opacity:.4;cursor:not-allowed;pointer-events:none}
/* ==== utilities.149.css ==== */
.auto-empty{text-align:center;padding:56px 20px;color:var(--faint)}

.auto-empty-t{font-size:var(--t-h3);font-weight:700;color:var(--ink);margin-top:14px;margin-bottom:6px}

.auto-empty-d{font-size:var(--t-body);max-width:340px;margin:0 auto;line-height:1.6}

/* --- builder --- */
.auto-box-builder{width:min(760px,94vw)}

.auto-builder-body{overflow-y:auto;padding:20px 24px;flex:1;display:flex;flex-direction:column;gap:2px}

.auto-flow-label{font-size:var(--t-xs);font-weight:600;color:var(--accent-700);margin:14px 0 8px}

[data-theme="dark"] .auto-flow-label{color:var(--accent-600)}

.auto-flow-label:first-child{margin-top:0}

.auto-flow-sub{color:var(--faint);font-weight:500;text-transform:none;letter-spacing:0;margin-left:6px}

.auto-flow-arrow{display:flex;justify-content:center;color:var(--line-3);margin:2px 0}
/* ==== components.112.css ==== */
.auto-card{background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-lg);padding:14px 16px}

.auto-card-row{display:flex;flex-wrap:wrap;gap:12px;align-items:flex-end}

.auto-field{display:flex;flex-direction:column;gap:5px;min-width:150px}

.auto-field-l{font-size:var(--t-xs);font-weight:600;color:var(--faint);}

.auto-select,.auto-input{
  border:1px solid var(--line);background:var(--surface);border-radius:var(--r-sm);
  padding:7px 10px;font-size:var(--t-body);color:var(--ink);outline:none;transition:var(--dur-fast);font-family:inherit;
}

.auto-select:focus,.auto-input:focus{border-color:var(--accent);box-shadow:var(--ring)}

.auto-input-num{width:64px;text-align:center}
/* ==== utilities.150.css ==== */
.cond-group{background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-lg);padding:12px 14px;margin-top:2px}

.cond-group.cond-root{background:var(--well)}

.cond-group .cond-group{margin:8px 0;background:var(--surface)}

.cond-group-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}

.cond-group-tag{font-size:var(--t-micro);font-weight:600;color:var(--faint)}
/* ==== components.113.css ==== */
.cond-op-toggle{display:inline-flex;background:var(--surface-3);border-radius:var(--r-sm);padding:2px;margin-bottom:10px;gap:2px}

.cond-op-toggle span{padding:5px 11px;font-size:var(--t-xs);font-weight:600;color:var(--muted);border-radius:var(--r-xs);cursor:pointer;transition:var(--dur-instant)}

.cond-op-toggle span.on{background:var(--surface);color:var(--ink);box-shadow:var(--shadow-xs)}
/* ==== utilities.151.css ==== */
.cond-items{display:flex;flex-direction:column;gap:6px}

.cond-leaf{display:grid;grid-template-columns:150px 130px 1fr auto 30px;gap:8px;align-items:center}
/* ==== components.114.css ==== */
.cond-not-toggle{display:flex;align-items:center;gap:5px;font-size:var(--t-sm);color:var(--faint);white-space:nowrap;cursor:pointer;user-select:none}

.cond-not-toggle input{margin:0;cursor:pointer}

.cond-not-toggle:has(input:checked){color:var(--danger);font-weight:600}
/* ==== utilities.152.css ==== */
.cond-novalue{color:var(--faint);text-align:center}

.cond-joiner{font-size:var(--t-micro);font-weight:700;color:var(--faint);text-align:center;letter-spacing:.06em;padding:1px 0}

.cond-empty{font-size:var(--t-sm);color:var(--faint);font-style:italic;padding:4px 2px}

.cond-add-row{display:flex;gap:8px;margin-top:10px}
/* ==== components.115.css ==== */
.auto-addbtn{
  display:inline-flex;align-items:center;gap:6px;font-size:var(--t-sm);font-weight:600;color:var(--accent-700);
  background:var(--accent-soft);padding:6px 12px;border-radius:var(--r-sm);transition:var(--dur-fast);
}

[data-theme="dark"] .auto-addbtn{color:var(--accent-600)}

.auto-addbtn:hover{filter:brightness(.97)}

.auto-addbtn-lg{margin-top:8px;align-self:flex-start;padding:8px 14px;font-size:var(--t-sm)}
/* ==== utilities.153.css ==== */
.auto-actions-list{display:flex;flex-direction:column;gap:8px;margin-top:4px}

.auto-action-row{display:flex;align-items:center;gap:10px;background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-md);padding:10px 12px}

.auto-action-num{width:20px;height:20px;border-radius:50%;background:var(--accent-soft);color:var(--accent-700);font-size:var(--t-micro);font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0}

[data-theme="dark"] .auto-action-num{color:var(--accent-600)}

.auto-action-params{display:flex;gap:8px;flex:1;min-width:0;flex-wrap:wrap;align-items:center}
/* ==== components.116.css ==== */
.auto-action-params .auto-select,.auto-action-params .auto-input{flex:1;min-width:110px}
/* ==== utilities.154.css ==== */
.auto-delay{display:flex;align-items:center;gap:6px;font-size:var(--t-xs);color:var(--faint);flex-shrink:0;white-space:nowrap}

.auto-test-block{margin-top:16px;padding-top:4px;border-top:1px solid var(--line)}

.auto-test-row{display:flex;gap:8px;align-items:center}

.auto-test-row .auto-select{flex:1}

.auto-test-result{margin-top:12px;padding:12px 14px;border-radius:var(--r-md);font-size:var(--t-sm);line-height:1.6}

.auto-test-result ul{margin:6px 0 0 18px;padding:0}

.auto-test-ok{background:var(--ok-soft);color:var(--ok)}

.auto-test-fail{background:var(--warn-soft);color:var(--warn);display:flex;align-items:center;gap:8px}

.auto-foot{display:flex;align-items:center;justify-content:space-between;padding:14px 22px;border-top:1px solid var(--line);background:var(--surface-2);flex-shrink:0}

/* --- журнал --- */
.auto-log-filters{display:flex;gap:6px;padding:12px 18px 0}

.auto-log-f{font-size:var(--t-sm);font-weight:600;color:var(--muted);padding:6px 12px;border-radius:var(--r-pill);transition:var(--dur-instant)}

.auto-log-f:hover{background:var(--surface-3)}

.auto-log-f.on{background:var(--accent-soft);color:var(--accent-700)}

[data-theme="dark"] .auto-log-f.on{color:var(--accent-600)}

.auto-log-row{display:flex;align-items:flex-start;gap:11px;padding:11px 12px;border-radius:var(--r-md);transition:background var(--dur-instant)}

.auto-log-row:hover{background:var(--surface-2)}

.auto-log-ic{width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-top:1px}

.auto-log-ok .auto-log-ic{background:var(--ok-soft);color:var(--ok)}

.auto-log-error .auto-log-ic{background:var(--danger-soft);color:var(--danger)}

.auto-log-test .auto-log-ic{background:var(--info-soft);color:var(--info)}

.auto-log-body{flex:1;min-width:0}

.auto-log-title{font-size:var(--t-body);font-weight:600;color:var(--ink)}
/* ==== features.043.css ==== */
.auto-log-task{font-weight:400;color:var(--muted)}
/* ==== utilities.155.css ==== */
.auto-log-msg{font-size:var(--t-sm);color:var(--muted);margin-top:2px;line-height:1.5}

.auto-log-error .auto-log-msg{color:var(--danger)}

.auto-log-time{font-size:var(--t-xs);color:var(--faint);flex-shrink:0;white-space:nowrap;padding-top:2px}

.auto-log-retry{display:flex;align-items:center;gap:5px;flex-shrink:0;padding:5px 10px;border-radius:var(--r-sm);border:1px solid var(--line-2);background:var(--surface);color:var(--muted);font-size:var(--t-sm);font-weight:600;cursor:pointer;transition:var(--dur-instant)}

.auto-log-retry:hover{border-color:var(--accent-line);color:var(--accent);background:var(--accent-soft)}

/* ============================================================
   TIMELINE 2.0
   ============================================================ */
.tl2-zoomgroup{display:inline-flex;background:var(--well);border:1px solid var(--line-2);border-radius:var(--r-sm);padding:2px;gap:2px}
/* ==== components.117.css ==== */
.tl2-zoombtn{padding:5px 11px;font-size:var(--t-sm);font-weight:600;color:var(--muted);border-radius:var(--r-xs);transition:var(--dur-instant)}

.tl2-zoombtn:hover{color:var(--ink)}

.tl2-zoombtn.active{background:var(--surface);color:var(--ink);box-shadow:var(--shadow-sm),inset 0 1px 0 var(--edge-hi)}
/* ==== utilities.156.css ==== */
.tl2-dot{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--accent);margin-left:4px;vertical-align:middle}

.chip-select-wrap{display:inline-flex}

.tl2-colorby{padding:7px 10px;font-size:var(--t-sm);border-radius:var(--r-pill);background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-xs);cursor:pointer}

.chip.on{background:var(--accent-soft);border-color:var(--accent-line);color:var(--accent-700)}

[data-theme="dark"] .chip.on{color:var(--accent-600)}

.tl2-count{font-family:var(--mono);font-size:var(--t-xs);color:var(--faint)}

.tl2-wrap{height:calc(100vh - var(--topbar-h) - 118px);display:flex;flex-direction:column}

.tl2-scroll{flex:1;overflow:auto;position:relative;background:var(--canvas)}

.tl2-inner{position:relative}
/* ==== layout.036.css ==== */
.tl2-header{position:sticky;top:0;z-index:6;display:flex;background:var(--canvas);border-bottom:1px solid var(--line)}

.tl2-header-corner{position:sticky;left:0;z-index:7;width:220px;flex-shrink:0;background:var(--canvas);border-right:1px solid var(--line)}

.tl2-header-scroller{position:relative}
/* ==== utilities.157.css ==== */
.tl2-band-row{position:relative;height:23px}

.tl2-band{position:absolute;top:0;height:23px;display:flex;align-items:center;padding-left:8px;font-size:var(--t-xs);font-weight:700;color:var(--ink-2);border-right:1px solid var(--line-2);box-sizing:border-box;overflow:hidden;white-space:nowrap;text-transform:capitalize}

.tl2-day-row{border-top:1px solid var(--line-2)}

.tl2-day{position:absolute;top:0;height:23px;display:flex;align-items:center;justify-content:center;font-family:var(--mono);font-size:var(--t-micro);color:var(--faint);border-right:1px solid var(--line-2);box-sizing:border-box}

.tl2-day.wknd{background:var(--well)}

.tl2-day.today{color:var(--accent-700);font-weight:700}

[data-theme="dark"] .tl2-day.today{color:var(--accent-600)}

.tl2-body{position:relative}

.tl2-row{display:flex;border-bottom:1px solid var(--line-2);box-sizing:border-box;content-visibility:auto;contain-intrinsic-size:0 32px}

.tl2-row-sec{background:var(--well)}

.tl2-label{
  position:sticky;left:0;z-index:3;width:220px;flex-shrink:0;
  display:flex;align-items:center;gap:6px;padding:0 10px;
  background:var(--canvas);border-right:1px solid var(--line);
  font-size:var(--t-sm);color:var(--ink-2);overflow:hidden;white-space:nowrap;
}

.tl2-row-sec .tl2-label-sec{font-weight:700;font-size:var(--t-xs);color:var(--ink);display:flex;align-items:center;gap:6px}

.tl2-seccount{font-family:var(--mono);font-size:var(--t-micro);color:var(--faint);font-weight:500}
/* ==== components.118.css ==== */
.tl2-label .avatar{flex-shrink:0;margin-right:-4px}
/* ==== utilities.158.css ==== */
.tl2-label-tx{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}

.tl2-track{position:relative;flex-shrink:0}

.tl2-today-line{position:absolute;top:0;bottom:0;width:2px;background:var(--accent);opacity:.55;z-index:1;pointer-events:none}

.tl2-deps{position:absolute;top:0;left:0;pointer-events:none;z-index:2;overflow:visible}

.tl2-bar{
  position:absolute;top:50%;transform:translateY(-50%);height:22px;border-radius:var(--r-xs);
  display:flex;align-items:center;padding:0 8px;font-size:var(--t-xs);font-weight:600;color:var(--on-solid);
  cursor:grab;box-shadow:var(--shadow-sm),inset 0 1px 0 rgba(255,255,255,.22);overflow:hidden;white-space:nowrap;
  transition:filter var(--dur-fast,var(--dur-fast)) var(--ease-standard,ease),box-shadow var(--dur-fast,var(--dur-fast)) var(--ease-standard,ease);
}

.tl2-bar:not(.dragging){transition:filter var(--dur-instant),box-shadow var(--dur-instant),left var(--dur,var(--dur)) var(--ease-out,ease),width var(--dur,var(--dur)) var(--ease-out,ease)}

.tl2-bar:hover{filter:brightness(1.08)}

.tl2-bar:focus-visible{outline:none;box-shadow:0 0 0 2px var(--canvas),0 0 0 4px var(--accent)}

.tl2-bar.dragging{cursor:grabbing;opacity:.92;box-shadow:var(--shadow-md);z-index:4;transition:none}

.tl2-bar.done{opacity:.5}

.tl2-bar.overdue{box-shadow:0 0 0 2px var(--danger),var(--shadow-sm)}

.tl2-bar.critical{box-shadow:0 0 0 2px var(--danger),var(--shadow-sm)}

.tl2-bar.critical.overdue{box-shadow:0 0 0 2px var(--danger),0 0 0 4px var(--danger-soft)}

.tl2-bar-tx{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;text-shadow:0 1px 2px rgba(0,0,0,.45)}

.tl2-h{position:absolute;top:0;bottom:0;width:7px;cursor:ew-resize}

.tl2-h-l{left:0}

.tl2-h-r{right:0}

.tl2-bar:hover .tl2-h{background:rgba(255,255,255,.4)}

.tl2-ms{
  position:absolute;top:50%;left:0;width:15px;height:15px;transform:translate(-50%,-50%) rotate(45deg);
  background:var(--accent);border-radius:3px;cursor:grab;box-shadow:var(--shadow-sm);
  transition:left var(--dur,var(--dur)) var(--ease-out,ease);
}

.tl2-ms.overdue{background:var(--danger)}

.tl2-ms.critical{box-shadow:0 0 0 2px var(--danger)}

.tl2-ms:hover{filter:brightness(1.1)}

.tl2-ms:focus-visible{outline:none;filter:brightness(1.1);box-shadow:0 0 0 2px var(--canvas),0 0 0 4px var(--accent)}

/* ============================================================
   WORKLOAD 2.0
   ============================================================ */
.wl-hrs-set{display:flex;align-items:center;gap:6px;font-size:var(--t-xs);color:var(--faint)}

.wl-wrap2{padding:18px var(--gutter) 48px;display:flex;flex-direction:column;gap:16px}

.wl-summary{display:flex;gap:12px;flex-wrap:wrap}
/* ==== components.119.css ==== */
.wl-sum-card{
  flex:1;min-width:150px;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:14px 18px;display:flex;flex-direction:column;gap:4px;box-shadow:var(--shadow-sm),inset 0 1px 0 var(--edge-hi);
}
/* ==== utilities.159.css ==== */
.wl-sum-n{font-size:26px;font-weight:700;letter-spacing:-.03em;color:var(--ink);font-variant-numeric:tabular-nums}
/* ==== components.120.css ==== */
.wl-sum-card.over .wl-sum-n{color:var(--danger)}

.wl-sum-card.free .wl-sum-n{color:var(--info)}
/* ==== utilities.160.css ==== */
.wl-sum-l{font-size:var(--t-sm);color:var(--muted)}

.wl-recs{background:var(--accent-soft-2);border:1px solid var(--accent-line);border-radius:var(--r-lg);padding:14px 18px;display:flex;flex-direction:column;gap:8px}

.wl-recs-head{font-size:var(--t-sm);font-weight:700;color:var(--accent-700);display:flex;align-items:center;gap:7px}

[data-theme="dark"] .wl-recs-head{color:var(--accent-600)}

.wl-recs-sub{font-weight:400;color:var(--faint);font-size:var(--t-xs)}

.wl-rec{font-size:var(--t-sm);color:var(--ink-2);line-height:1.5;padding-left:20px;position:relative}

.wl-rec:before{content:'';position:absolute;left:4px;top:7px;width:5px;height:5px;border-radius:50%;background:var(--accent)}

.wl-rows{display:flex;flex-direction:column;gap:8px}

.wl-row2{
  display:grid;grid-template-columns:230px 1fr 150px;gap:20px;align-items:center;
  padding:14px 18px;border-radius:var(--r-lg);border:1px solid var(--line);background:var(--surface);
  box-shadow:var(--shadow-xs),inset 0 1px 0 var(--edge-hi);transition:box-shadow var(--dur-fast),border-color var(--dur-fast);
}

.wl-row2:hover{box-shadow:var(--shadow-sm),inset 0 1px 0 var(--edge-hi);border-color:var(--line-3)}

.wl-name{display:flex;align-items:center;gap:11px;min-width:0}

.wl-name-tx{font-weight:600;font-size:var(--t-body);color:var(--ink)}

.wl-role{font-size:var(--t-xs);color:var(--faint);margin-top:1px}

.wl-bar-col{display:flex;flex-direction:column;gap:7px;min-width:0}

.wl-bar2{position:relative;height:10px;border-radius:var(--r-pill);background:var(--well);overflow:visible;box-shadow:inset 0 0 0 1px var(--line-2)}

.wl-bar2-fill{height:100%;border-radius:var(--r-pill);transition:width var(--dur-slow,var(--dur-slow)) var(--ease-out,ease);box-shadow:inset 0 1px 0 rgba(255,255,255,.25)}

.wl-bar2-over{position:absolute;top:-3px;bottom:-3px;width:2px;background:var(--danger)}

.wl-bar2-legend{display:flex;align-items:center;gap:9px;font-size:var(--t-xs);color:var(--muted);flex-wrap:wrap}

.wl-status-tag{font-size:var(--t-micro);font-weight:700;padding:2px 8px;border-radius:var(--r-pill)}

.wl-overdue-tx{color:var(--danger)}

.wl-forecast{display:flex;flex-direction:column;align-items:center;gap:4px}

.wl-spark{display:flex;align-items:flex-end;gap:4px;height:28px}

.wl-spark-bar{width:14px;height:100%;display:flex;align-items:flex-end;background:var(--well);border-radius:2px;overflow:hidden}

.wl-spark-bar>div{width:100%;border-radius:2px 2px 0 0;transition:height var(--dur-slow,var(--dur-slow)) var(--ease-out,ease)}

.wl-spark-label{font-size:var(--t-micro);color:var(--faint);}

.wl-redist-list{display:flex;flex-direction:column;gap:2px;max-height:340px;overflow-y:auto}

.wl-redist-row{display:flex;align-items:center;gap:10px;padding:9px 8px;border-radius:var(--r-sm);cursor:pointer;font-size:var(--t-sm)}

.wl-redist-row:hover{background:var(--surface-2)}
/* ==== features.044.css ==== */
.wl-redist-task{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ink-2)}
/* ==== utilities.161.css ==== */
.wl-redist-arrow{display:flex;align-items:center;gap:4px;color:var(--muted);white-space:nowrap;font-size:var(--t-xs)}

.wl-redist-hrs{font-family:var(--mono);font-size:var(--t-xs);color:var(--faint);flex-shrink:0}
/* ==== features.045.css ==== */
/* ============================================================
   ПОИСК НА ЕСТЕСТВЕННОМ ЯЗЫКЕ
   ============================================================ */
.search-chips{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-top:12px}

.search-reason{display:flex;align-items:center;gap:5px;font-size:var(--t-xs);color:var(--accent-700);padding:2px 12px 8px 44px;margin-top:-4px}

[data-theme="dark"] .search-reason{color:var(--accent-600)}

.cmdk-sec:empty{display:none}

.cmdk-fav{margin-left:auto;flex-shrink:0;width:20px;height:20px;border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;color:var(--line-3);opacity:0;transition:var(--dur-instant)}

.cmdk-item:hover .cmdk-fav,.cmdk-item.active .cmdk-fav{opacity:1}

.cmdk-fav.on{opacity:1;color:var(--star)}

.cmdk-fav.on svg{fill:var(--star)}

.cmdk-remove{margin-left:auto;flex-shrink:0;width:20px;height:20px;border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;color:var(--faint);opacity:0;transition:var(--dur-instant)}

.cmdk-item:hover .cmdk-remove{opacity:1}

.cmdk-remove:hover{background:var(--danger-soft);color:var(--danger)}
/* ==== utilities.162.css ==== */
/* ============================================================
   ЦЕНТР ИНТЕГРАЦИЙ
   ============================================================ */
.int-intro{background:var(--accent-soft-2);border:1px solid var(--accent-line);border-radius:var(--r-lg);padding:16px 20px;margin-bottom:20px}

.int-intro-t{font-size:var(--t-h3);font-weight:700;color:var(--ink);margin-bottom:6px}

.int-intro-d{font-size:var(--t-sm);color:var(--ink-2);line-height:1.6}

.int-group{margin-bottom:24px}

.int-group-title{font-size:var(--t-xs);font-weight:600;color:var(--faint);margin-bottom:10px}
/* ==== layout.037.css ==== */
.int-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:14px}
/* ==== components.121.css ==== */
.int-card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;box-shadow:var(--shadow-sm),inset 0 1px 0 var(--edge-hi)}

.int-card-oauth{opacity:.85}

.int-card-inbound{margin-bottom:20px}

.int-card-head{display:flex;align-items:center;gap:9px;padding:13px 15px;border-bottom:1px solid var(--line)}
/* ==== utilities.163.css ==== */
.int-ic{display:flex;color:var(--muted);flex-shrink:0}

.int-name{font-weight:600;font-size:var(--t-body);color:var(--ink);flex:1}
/* ==== components.122.css ==== */
.int-badge{font-size:var(--t-micro);font-weight:700;text-transform:uppercase;letter-spacing:.05em;padding:2px 8px;border-radius:var(--r-pill);flex-shrink:0}

.int-badge-on{background:var(--ok-soft);color:var(--ok)}

.int-badge-off{background:var(--surface-3);color:var(--faint)}

.int-badge-need{background:var(--warn-soft);color:var(--warn)}

.int-card-body{padding:13px 15px}

.int-card-body .form-row{margin-bottom:10px}

.int-card-body .form-row:last-of-type{margin-bottom:12px}

.int-card-actions{display:flex;gap:8px;flex-wrap:wrap}
/* ==== utilities.164.css ==== */
.int-test-out{margin-top:10px;font-size:var(--t-xs);line-height:1.5;padding:8px 10px;border-radius:var(--r-sm);display:none}

.int-test-out:not(:empty){display:block}

.int-test-pending{background:var(--surface-3);color:var(--muted)}

.int-test-ok{background:var(--ok-soft);color:var(--ok)}

.int-test-fail{background:var(--danger-soft);color:var(--danger)}

.int-hook-url{font-family:var(--mono);font-size:var(--t-xs);background:var(--well);border-radius:var(--r-sm);padding:9px 12px;margin-top:10px;word-break:break-all;display:flex;align-items:center;gap:8px}

.int-webhook-list{margin-top:10px;display:flex;flex-direction:column;gap:6px}

.int-webhook-row{display:flex;align-items:center;gap:8px;font-size:var(--t-xs);padding:7px 9px;background:var(--surface-2);border-radius:var(--r-sm)}

.int-webhook-url{font-family:var(--mono);color:var(--ink-2);flex:1;overflow:hidden}

.int-webhook-ev{color:var(--faint);flex-shrink:0}

/* ============================================================
   МОНИТОР ПРОИЗВОДИТЕЛЬНОСТИ
   ============================================================ */
.perfmon{
  position:fixed;bottom:20px;right:20px;z-index:98;width:270px;
  background:var(--raised);border:1px solid var(--line);border-radius:var(--r-lg);
  box-shadow:var(--shadow-lg),inset 0 1px 0 var(--edge-hi);padding:12px 14px 10px;
  font-family:var(--mono);animation:cmdkPop var(--dur-slow,250ms) cubic-bezier(.16,1,.3,1);
}

.perfmon-head{display:flex;align-items:center;gap:6px;font-family:inherit;font-size:var(--t-xs);font-weight:600;color:var(--ink);margin-bottom:8px;}

.perfmon-x{margin-left:auto;width:20px;height:20px;border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;color:var(--faint)}

.perfmon-x:hover{background:var(--surface-3);color:var(--ink)}

.perfmon-row{display:flex;justify-content:space-between;align-items:baseline;font-size:var(--t-xs);color:var(--muted);padding:3px 0}

.perfmon-row b{color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums}

.perfmon-row b.perfmon-bad{color:var(--danger)}

.perfmon-note{font-family:var(--ui,inherit);font-size:var(--t-micro);color:var(--faint);line-height:1.5;margin-top:8px;padding-top:8px;border-top:1px solid var(--line-2)}

/* ============================================================
   ИНДИКАТОР «НЕ ПОДТВЕРЖДЕНО СЕРВЕРОМ» — Optimistic UI
   ============================================================ */
.row-unsynced{color:var(--warn);background:var(--warn-soft);animation:unsyncedPulse 1.6s ease-in-out infinite}

@media(prefers-reduced-motion:reduce){.row-unsynced{animation:none}}

@keyframes unsyncedPulse{0%,100%{opacity:.5}50%{opacity:1}}

/* ============================================================
   ДИАЛОГ РАЗРЕШЕНИЯ КОНФЛИКТА СОХРАНЕНИЯ
   ============================================================ */
.conflict-intro{font-size:var(--t-body);color:var(--ink-2);line-height:1.55;margin-bottom:14px}

.conflict-cols-head{display:grid;grid-template-columns:110px 1fr 1fr;gap:8px;font-size:var(--t-micro);font-weight:600;color:var(--faint);padding:0 2px;margin-top:10px}

.conflict-diff{border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden}

.conflict-diff-row{display:grid;grid-template-columns:110px 1fr 1fr;gap:8px;padding:8px 10px;font-size:var(--t-sm);border-bottom:1px solid var(--line-2)}

.conflict-diff-row:last-child{border-bottom:none}

.conflict-diff-key{color:var(--faint);font-family:var(--mono);font-size:var(--t-xs);align-self:center}

.conflict-diff-val{padding:4px 8px;border-radius:var(--r-xs);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.conflict-diff-val.mine{background:var(--accent-soft);color:var(--accent-700)}

.conflict-diff-val.theirs{background:var(--warn-soft);color:var(--warn)}

[data-theme="dark"] .conflict-diff-val.mine{color:var(--accent-600)}
/* ==== features.046.css ==== */
/* ============================================================
   ПОИСК ПО НАСТРОЙКАМ
   ============================================================ */
.st-search-wrap{position:relative;margin-top:14px;max-width:420px}
/* ==== components.123.css ==== */
.st-search-input{width:100%;padding:9px 14px 9px 36px;border:1px solid var(--line);border-radius:var(--r-lg);background:var(--surface);font-size:var(--t-body);color:var(--ink);outline:none;transition:var(--dur-fast)}

.st-search-input:focus{border-color:var(--accent);box-shadow:var(--ring)}
/* ==== features.047.css ==== */
.st-search-wrap svg{position:absolute;left:12px;top:50%;transform:translateY(-50%);color:var(--faint);pointer-events:none}

.st-search-results{margin-top:6px;max-width:420px;border:1px solid var(--line);border-radius:var(--r-md);background:var(--surface);box-shadow:var(--shadow-md);overflow:hidden}

.st-search-hit{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:9px 13px;cursor:pointer;border-bottom:1px solid var(--line-2)}

.st-search-hit:last-child{border-bottom:none}

.st-search-hit:hover{background:var(--surface-2)}

.st-search-label{font-size:var(--t-sm);color:var(--ink-2);font-weight:500}

.st-search-hint{font-size:var(--t-xs);color:var(--faint);flex-shrink:0;text-align:right}
/* ==== layout.038.css ==== */
/* ============================================================
   ГАЛЕРЕЯ ШАБЛОНОВ АВТОМАТИЗАЦИЙ
   ============================================================ */
.auto-tpl-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
/* ==== utilities.165.css ==== */
@media(max-width:640px){.auto-tpl-grid{grid-template-columns:1fr}}
/* ==== components.124.css ==== */
.auto-tpl-card{border:1px solid var(--line);border-radius:var(--r-md);padding:13px 14px;cursor:pointer;background:var(--surface);transition:var(--dur-fast);display:flex;flex-direction:column;gap:6px}

.auto-tpl-card:hover{border-color:var(--accent-line);box-shadow:var(--shadow-sm);background:var(--accent-soft-2)}
/* ==== utilities.166.css ==== */
.auto-tpl-name{font-size:var(--t-body);font-weight:600;color:var(--ink)}

.auto-tpl-desc{font-size:var(--t-xs);color:var(--muted);line-height:1.5;flex:1}

.auto-tpl-meta{display:flex;gap:6px;flex-wrap:wrap;margin-top:2px}
/* ==== components.125.css ==== */
/* ============================================================
   МНОЖЕСТВЕННОЕ ВЫДЕЛЕНИЕ И ПЕРЕТАСКИВАНИЕ ГРУППОЙ НА ДОСКЕ
   ============================================================ */
.card-selected{box-shadow:0 0 0 2px var(--accent),var(--shadow-sm)!important;background:var(--accent-soft-2)}

.card-selected.dragging{opacity:.5}

.board-drag-badge{position:fixed;top:-1000px;left:-1000px;display:flex;align-items:center;gap:6px;padding:7px 13px;border-radius:var(--r-pill);background:var(--accent);color:var(--on-solid);font-size:var(--t-sm);font-weight:600;box-shadow:var(--shadow-lg);pointer-events:none;z-index:999}
/* ==== features.048.css ==== */
/* ============================================================
   PRESENCE В ЗАДАЧЕ — «смотрит» / «печатает…»
   ============================================================ */
.task-presence{display:flex;flex-direction:column;gap:3px;margin:2px 0 6px;min-height:0}

.task-presence:empty{margin:0}

.task-presence-viewing{display:flex;align-items:center;gap:5px;font-size:var(--t-xs);color:var(--faint)}

.task-presence-typing{display:flex;align-items:center;gap:6px;font-size:var(--t-xs);color:var(--accent-700);font-weight:500}

[data-theme="dark"] .task-presence-typing{color:var(--accent-600)}
/* ==== utilities.167.css ==== */
.typing-dots{display:inline-flex;gap:2px}

.typing-dots i{width:4px;height:4px;border-radius:50%;background:currentColor;display:inline-block;animation:typingDot 1.2s infinite ease-in-out}

.typing-dots i:nth-child(2){animation-delay:.15s}

.typing-dots i:nth-child(3){animation-delay:.3s}

@keyframes typingDot{0%,60%,100%{opacity:.25;transform:translateY(0)}30%{opacity:1;transform:translateY(-2px)}}

/* ============================================================
   ПРЕДУПРЕЖДЕНИЕ О ХРАНЕНИИ ТОКЕНА НА УСТРОЙСТВЕ
   ============================================================ */
.int-token-warn{display:flex;align-items:flex-start;gap:7px;font-size:var(--t-xs);line-height:1.5;color:var(--warn);background:var(--warn-soft);border-radius:var(--r-sm);padding:8px 10px;margin:8px 0}

.int-token-warn svg{flex-shrink:0;margin-top:1px}

/* ============================================================
   РОЛИ НА УРОВНЕ ПРОЕКТА
   ============================================================ */
.proj-role-row{display:flex;align-items:center;gap:10px;padding:9px 4px;border-bottom:1px solid var(--line-2)}

.proj-role-row:last-child{border-bottom:none}

.proj-role-name{flex:1;min-width:0;font-size:var(--t-body);color:var(--ink-2);display:flex;flex-direction:column;gap:1px}

.proj-role-global{font-size:var(--t-micro);color:var(--faint);font-weight:400}

.proj-role-fixed{font-size:var(--t-xs);color:var(--faint);font-family:var(--mono)}
/* ==== features.049.css ==== */
/* ============================================================
   СОХРАНЁННЫЕ ПРЕДСТАВЛЕНИЯ ФИЛЬТРОВ
   ============================================================ */
.view-item{display:flex!important;align-items:center;justify-content:space-between;gap:8px}

.view-item-name{display:flex;align-items:center;gap:7px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.view-item-del{flex-shrink:0;width:18px;height:18px;border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;color:var(--faint);opacity:0;transition:var(--dur-instant)}

.view-item:hover .view-item-del{opacity:1}

.view-item-del:hover{background:var(--danger-soft);color:var(--danger)}
/* ==== layout.039.css ==== */
/* ============================================================
   ФУНКЦИИ ИИ
   ============================================================ */
.ai-panel-actions{display:flex;gap:8px;flex-wrap:wrap;margin:2px 0 6px}
/* ==== utilities.168.css ==== */
.ai-out{font-size:var(--t-body);line-height:1.6;color:var(--ink-2);white-space:pre-wrap;min-height:40px}

.ai-out-loading{color:var(--faint);font-style:italic}

.ai-note{display:flex;align-items:flex-start;gap:7px;margin-top:14px;padding-top:10px;border-top:1px solid var(--line-2);font-size:var(--t-xs);line-height:1.5;color:var(--faint)}

.ai-note svg{flex-shrink:0;margin-top:2px}
/* ==== components.126.css ==== */
/* ============================================================
   ДОСТУПНОСТЬ — ФОКУС ДЛЯ КЛАВИАТУРНОЙ НАВИГАЦИИ
   ============================================================ */
.menu-item:focus-visible,.st-tab:focus-visible,[role="tab"]:focus-visible,[role="menuitem"]:focus-visible{outline:2px solid var(--accent);outline-offset:-2px;background:var(--accent-soft-2)}

.menu-item:focus{outline:none}

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

/* ============================================================
   ТАЙМ-ТРЕКИНГ
   ============================================================ */
.timer-btn{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;border-radius:var(--r-lg);border:1px solid var(--line);background:var(--surface);color:var(--ink-2);font-size:var(--t-sm);font-weight:500;cursor:pointer;transition:var(--dur-fast)}

.timer-btn:hover{border-color:var(--accent-line);background:var(--accent-soft-2)}

.timer-btn.running{background:var(--danger-soft);border-color:var(--danger);color:var(--danger)}
/* ==== utilities.169.css ==== */
.timer-total{margin-left:10px;font-size:var(--t-sm);color:var(--faint);font-family:var(--mono)}

.time-entries{margin-top:8px;border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden}

.time-entry-row{display:flex;align-items:center;gap:8px;padding:7px 10px;font-size:var(--t-xs);border-bottom:1px solid var(--line-2)}

.time-entry-row:last-child{border-bottom:none}

.time-entry-row.running{background:var(--danger-soft)}

.time-entry-who{width:60px;flex-shrink:0;color:var(--faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.time-entry-inp{border:1px solid transparent;background:transparent;font-size:var(--t-xs);color:var(--ink-2);font-family:var(--mono);border-radius:var(--r-xs);padding:2px 4px;width:150px}

.time-entry-inp:hover,.time-entry-inp:focus{border-color:var(--line);background:var(--surface)}

.time-entry-sep{color:var(--faint)}

.time-entry-live{color:var(--danger);font-weight:600;width:150px}

.time-entry-dur{margin-left:auto;color:var(--ink-2);font-weight:600;font-family:var(--mono)}

.time-entry-del{flex-shrink:0;width:18px;height:18px;border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;color:var(--faint)}

.time-entry-del:hover{background:var(--danger-soft);color:var(--danger)}
/* ==== components.127.css ==== */
.timer-badge{color:var(--danger);background:var(--danger-soft);animation:timerPulse 1.4s infinite}
/* ==== utilities.170.css ==== */
@media(prefers-reduced-motion:reduce){.timer-badge{animation:none}}

.wl-hrs-lbl{font-size:var(--t-sm);color:var(--muted);margin-right:8px}

@keyframes timerPulse{0%,100%{opacity:1}50%{opacity:.35}}

.wl-tracked{font-size:var(--t-xs);color:var(--faint);margin-top:3px;display:flex;align-items:center;gap:4px}
/* ==== features.050.css ==== */
/* ============================================================
   ДОКУМЕНТЫ ПРОЕКТА
   ============================================================ */
.docs-page{padding:4px 0}

.docs-head{display:flex;justify-content:flex-end;margin-bottom:14px}
/* ==== components.128.css ==== */
.seg-tabs{display:flex;gap:4px;background:var(--surface-2);border-radius:var(--r-lg);padding:3px;margin-bottom:14px}

.seg-tab{flex:1;border:none;background:transparent;color:var(--faint);font-size:var(--t-sm);font-weight:600;padding:7px 10px;border-radius:var(--r-md);cursor:pointer;transition:background var(--dur-instant),color var(--dur-instant)}

.seg-tab.on{background:var(--raised);color:var(--ink)}

.team-inv-card{border:1px solid var(--line);border-radius:var(--r-xl);padding:14px;margin-bottom:10px}

.team-inv-card .tic-head{font-size:var(--t-h3);font-weight:700;margin-bottom:4px}

.team-inv-card .tic-sub{font-size:var(--t-sm);color:var(--faint);margin-bottom:10px}

.team-inv-card .tic-projects{font-size:var(--t-xs);color:var(--faint);margin-bottom:10px;line-height:1.5}

.team-inv-card .tic-actions{display:flex;gap:8px}
/* ==== features.051.css ==== */
.docs-list{display:flex;flex-direction:column;gap:1px;border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden}

.doc-row{display:flex;align-items:center;gap:12px;padding:12px 14px;background:var(--surface);cursor:pointer;border-bottom:1px solid var(--line-2);transition:var(--dur-instant)}

.doc-row:last-child{border-bottom:none}

.doc-row:hover{background:var(--surface-2)}

.doc-row-ic{color:var(--faint);flex-shrink:0}

.doc-row-main{flex:1;min-width:0}

.doc-row-title{font-size:var(--t-body);font-weight:500;color:var(--ink)}

.doc-row-preview{font-size:var(--t-sm);color:var(--faint);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.doc-row-preview.empty{font-style:italic}

.doc-row-meta{font-size:var(--t-xs);color:var(--faint);flex-shrink:0}

.doc-row-del{flex-shrink:0;width:26px;height:26px;border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;color:var(--faint);opacity:0;transition:var(--dur-instant)}

.doc-row:hover .doc-row-del{opacity:1}

.doc-row-del:hover{background:var(--danger-soft);color:var(--danger)}

.doc-editor{max-width:760px}

.doc-editor-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}

.doc-editor-actions{display:flex;gap:8px}

.doc-title-inp{width:100%;font-size:var(--t-h1);font-weight:700;border:none;background:transparent;color:var(--ink);padding:4px 0;margin-bottom:10px;outline:none;border-bottom:2px solid transparent}

.doc-title-inp:focus{border-bottom-color:var(--accent)}

.doc-title-view{font-size:var(--t-h1);font-weight:700;color:var(--ink);margin-bottom:14px}

.doc-area{width:100%;min-height:400px;border:1px solid var(--line);border-radius:var(--r-md);padding:14px;font-family:var(--mono);font-size:var(--t-body);line-height:1.6;color:var(--ink-2);background:var(--surface);resize:vertical}

.doc-body-view{font-size:var(--t-h3);line-height:1.7;color:var(--ink-2)}

/* ============================================================
   ДОКУМЕНТАЦИЯ ПУБЛИЧНОГО API
   ============================================================ */
.api-doc-block{margin:12px 0}

.api-doc-h{font-size:var(--t-sm);font-weight:600;color:var(--ink-2);margin-bottom:6px}
/* ==== utilities.171.css ==== */
.api-example{background:var(--ink);color:var(--canvas);border-radius:var(--r-sm);padding:11px 13px;font-family:var(--mono);font-size:var(--t-xs);line-height:1.6;overflow-x:auto;white-space:pre;margin:0 0 6px}

[data-theme="dark"] .api-example{background:var(--surface-3);border:1px solid var(--line-3)}
/* ==== features.052.css ==== */
.api-doc-block code{background:var(--surface-2);padding:1px 5px;border-radius:var(--r-xs);font-size:var(--t-xs)}
/* ==== utilities.172.css ==== */
/* ============================================================
   ПЕРЕКЛЮЧАТЕЛЬ ПОРТФЕЛЕЙ
   ============================================================ */
.pf-switcher{display:flex;gap:6px;flex-wrap:wrap;margin:22px 0 4px;padding:0 var(--gutter)}
/* ==== components.129.css ==== */
.pf-switch-btn{padding:6px 13px;border-radius:var(--r-lg);border:1px solid var(--line);background:var(--surface);color:var(--muted);font-size:var(--t-sm);font-weight:500;cursor:pointer;transition:var(--dur-instant)}

.pf-switch-btn:hover{border-color:var(--accent-line);color:var(--ink-2)}

.pf-switch-btn.active{background:var(--accent);border-color:var(--accent);color:var(--on-solid)}
/* ==== utilities.173.css ==== */
.proj-tile-more{display:flex;align-items:center;justify-content:center;padding:14px;color:var(--faint);font-size:var(--t-sm);text-align:center}
/* ==== components.130.css ==== */
/* ============================================================
   НОВЫЕ ДЕЙСТВИЯ АВТОМАТИЗАЦИИ И ВЕТКА «ИНАЧЕ»
   ============================================================ */
.auto-addbtn-ghost{display:inline-flex;align-items:center;gap:6px;margin-top:10px;padding:7px 13px;border:1px dashed var(--line);border-radius:var(--r-lg);background:transparent;color:var(--faint);font-size:var(--t-sm);cursor:pointer;transition:var(--dur-instant)}

.auto-addbtn-ghost:hover{border-color:var(--accent-line);color:var(--accent-700);background:var(--accent-soft-2)}
/* ==== utilities.174.css ==== */
.auto-inline-note{display:flex;align-items:flex-start;gap:6px;font-size:var(--t-xs);color:var(--faint);margin-top:4px;line-height:1.5}

.auto-inline-note.warn{color:var(--warn)}

/* ============================================================
   RBAC — РОЛИ И ПРАВА
   ============================================================ */
.rbac-box{max-width:1100px}
/* ==== layout.040.css ==== */
.rbac-layout{display:flex;gap:0;flex:1;min-height:0;overflow:hidden}
/* ==== utilities.175.css ==== */
.rbac-roles-col{width:220px;flex-shrink:0;border-right:1px solid var(--line);overflow-y:auto;padding:10px}
/* ==== components.131.css ==== */
.rbac-role-tab{display:flex;flex-direction:column;gap:3px;padding:9px 11px;border-radius:var(--r-md);cursor:pointer;margin-bottom:2px;transition:var(--dur-instant)}

.rbac-role-tab:hover{background:var(--surface-2)}

.rbac-role-tab.active{background:var(--accent-soft-2);box-shadow:inset 0 0 0 1px var(--accent-line)}
/* ==== utilities.176.css ==== */
.rbac-role-name{font-size:var(--t-body);font-weight:600;color:var(--ink)}
/* ==== components.132.css ==== */
.rbac-role-badge{font-size:var(--t-micro);color:var(--faint)}

.rbac-role-badge.fixed{color:var(--faint)}
/* ==== utilities.177.css ==== */
.rbac-matrix-col{flex:1;overflow-y:auto;padding:16px 22px}

.rbac-matrix-head{margin-bottom:10px}

.rbac-matrix-title{font-size:var(--t-h2);font-weight:700;color:var(--ink);margin-bottom:8px}

.rbac-custom-actions{display:flex;gap:8px;align-items:center;margin:10px 0;flex-wrap:wrap}

.rbac-name-inp{max-width:220px}

.rbac-matrix-body{border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden;margin-top:10px}

.rbac-perm-row{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;border-bottom:1px solid var(--line-2);font-size:var(--t-body)}

.rbac-perm-row:last-child{border-bottom:none}

.rbac-perm-name{color:var(--ink-2)}

.rbac-perm-inherited{display:block;font-size:var(--t-micro);color:var(--faint);font-weight:400;margin-top:1px}
/* ==== components.133.css ==== */
.rbac-toggle{position:relative;display:inline-block;width:34px;height:20px;flex-shrink:0}

.rbac-toggle input{opacity:0;width:0;height:0}

.rbac-toggle-slider{position:absolute;inset:0;background:var(--line);border-radius:var(--r-pill);transition:var(--dur-fast);cursor:pointer}

.rbac-toggle-slider:before{content:'';position:absolute;width:16px;height:16px;left:2px;top:2px;background:#fff;border-radius:50%;transition:var(--dur-fast)}

.rbac-toggle input:checked+.rbac-toggle-slider{background:var(--accent)}

.rbac-toggle input:checked+.rbac-toggle-slider:before{transform:translateX(14px)}

.rbac-toggle.disabled .rbac-toggle-slider{cursor:default;opacity:.55}
/* ==== utilities.178.css ==== */
.rbac-bulk-box{border:1px solid var(--line);border-radius:var(--r-md);padding:16px}

.rbac-bulk-title{font-size:var(--t-body);font-weight:600;color:var(--ink);margin-bottom:10px}
/* ==== layout.041.css ==== */
.rbac-bulk-grid{display:flex;gap:20px}
/* ==== features.053.css ==== */
.rbac-bulk-members{flex:1;max-height:220px;overflow-y:auto;border:1px solid var(--line-2);border-radius:var(--r-sm);padding:6px}

.rbac-member-row{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:var(--r-xs);cursor:pointer;font-size:var(--t-sm)}

.rbac-member-row:hover{background:var(--surface-2)}
/* ==== utilities.179.css ==== */
.rbac-bulk-controls{width:260px;flex-shrink:0;display:flex;flex-direction:column;gap:6px}

/* ============================================================
   ТИПЫ СВЯЗЕЙ И ПРЕДУПРЕЖДЕНИЯ О КОНФЛИКТАХ
   ============================================================ */
.dep-type-tag{font-family:var(--mono);font-size:var(--t-micro);font-weight:700;color:var(--faint);background:var(--surface-2);border-radius:var(--r-xs);padding:2px 5px;flex-shrink:0;cursor:help}

.dep-item.dep-conflict{background:var(--warn-soft);border-radius:var(--r-sm)}
/* ==== components.134.css ==== */
.dep-conflict-badge{color:var(--warn);flex-shrink:0;display:flex;cursor:help}
/* ==== utilities.180.css ==== */
.dep-type-item{display:flex;flex-direction:column;gap:1px;padding:8px 12px!important}

.dep-type-l{font-size:var(--t-sm);font-weight:600;color:var(--ink)}

.dep-type-h{font-size:var(--t-xs);color:var(--faint)}

/* ============================================================
   ИНТЕРАКТИВНАЯ СХЕМА ЗАВИСИМОСТЕЙ
   ============================================================ */
.dg-box{max-width:none;width:min(1400px,96vw)}

.dg-legend{display:flex;gap:14px;align-items:center;margin-right:14px;flex-wrap:wrap}

.dg-legend-item{display:flex;align-items:center;gap:5px;font-size:var(--t-xs);color:var(--faint)}

.dg-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}

.dg-canvas-wrap{flex:1;overflow:auto;padding:20px;background:var(--canvas-2,var(--surface-2))}

.dg-canvas{display:block}

.dg-node rect:first-child{transition:filter var(--dur-instant)}

.dg-node:hover rect:first-child{filter:brightness(.97)}

[data-theme="dark"] .dg-node:hover rect:first-child{filter:brightness(1.15)}

.dg-node.dg-done text{opacity:.5}

/* ============================================================
   AI PROJECT MANAGER — ЧАТ
   ============================================================ */
.ai-chat-box{width:min(640px,94vw);max-width:640px;height:min(680px,88vh);display:flex;flex-direction:column}

.ai-chat-quickrow{display:flex;gap:7px;flex-wrap:wrap;padding:10px 20px;border-bottom:1px solid var(--line-2)}

.ai-chat-chip{display:inline-flex;align-items:center;gap:5px;padding:6px 11px;border-radius:var(--r-lg);border:1px solid var(--line);background:var(--surface);color:var(--ink-2);font-size:var(--t-xs);cursor:pointer;transition:var(--dur-instant)}

.ai-chat-chip:hover{border-color:var(--accent-line);background:var(--accent-soft-2);color:var(--accent-700)}

.ai-chat-scroll{flex:1;overflow-y:auto;padding:16px 20px;display:flex;flex-direction:column;gap:12px}

.ai-chat-msg{display:flex;max-width:85%}

.ai-chat-msg.ai-chat-user{align-self:flex-end}

.ai-chat-msg.ai-chat-ai{align-self:flex-start}

.ai-chat-bubble{padding:10px 14px;border-radius:var(--r-lg);font-size:var(--t-body);line-height:1.55;white-space:pre-wrap}

.ai-chat-user .ai-chat-bubble{background:var(--accent);color:var(--on-solid);border-radius:var(--r-lg) 14px 4px 14px}

.ai-chat-ai .ai-chat-bubble{background:var(--surface-2);color:var(--ink-2);border-radius:var(--r-lg) 14px 14px 4px}

.ai-chat-msg.ai-chat-error .ai-chat-bubble{background:var(--danger-soft);color:var(--danger)}

.ai-thinking-dots{display:inline-flex;gap:3px}

.ai-thinking-dots span{width:6px;height:6px;border-radius:50%;background:var(--faint);animation:aiThinkDot 1.1s infinite}

.ai-thinking-dots span:nth-child(2){animation-delay:.15s}

.ai-thinking-dots span:nth-child(3){animation-delay:.3s}

@keyframes aiThinkDot{0%,100%{opacity:.25}50%{opacity:1}}
/* ==== components.135.css ==== */
.ai-chat-inputrow{display:flex;gap:8px;padding:14px 20px;border-top:1px solid var(--line-2)}

.ai-chat-input{flex:1;border:1px solid var(--line);border-radius:var(--r-lg);padding:9px 14px;font-size:var(--t-body);background:var(--surface);color:var(--ink)}

.ai-chat-input:focus{border-color:var(--accent);box-shadow:var(--ring)}

/* ============================================================
   СЛОЙ ВИЗУАЛЬНОГО РЕДИЗАЙНА
   ------------------------------------------------------------
   Отдельный слой в конце таблицы стилей, а не правки по всему
   файлу: так весь визуальный язык виден одним куском, его можно
   целиком прочитать, сравнить и при необходимости откатить, не
   выковыривая изменения из трёх тысяч строк. Ни одно правило
   здесь не меняет разметку, обработчики или поведение — только
   внешний вид.

   Три принципа, из которых выведено остальное:
   1. Край обозначает граница, а не тень. Тень оставлена только
      тому, что действительно висит над интерфейсом — меню,
      модальные окна, выпадающие панели.
   2. Акцент — отметка важного, а не фон. Фиолетовый остаётся у
      главного действия, активного состояния и фокуса; всё
      остальное живёт на нейтральной шкале.
   3. Второстепенное — тише. Служебные подписи, счётчики и
      метаданные снижены по контрасту, чтобы содержимое
      (название задачи, текст, цифра) читалось первым.
   ============================================================ */

/* ---------- 1. Плоскость: снятие лишней «приподнятости» ------- */
/* Инерция прежнего оформления: почти каждый элемент нёс тень и
   белую блик-кромку сверху. По отдельности приём хорош, но когда
   приподнято всё сразу, приподнятым не выглядит ничто — только
   картинка становится мутной. */
.btn-primary,.btn-create,.tb-create,.tb-create-caret{box-shadow:none}

.btn-ghost,.chip{box-shadow:none}

.card{box-shadow:none}

.card:hover{box-shadow:none;transform:none;border-color:var(--line-3);background:var(--surface)}
/* ==== layout.042.css ==== */
.nav-item.active,.proj-item.active{box-shadow:none}
/* ==== utilities.181.css ==== */
.empty-ic{box-shadow:none}
/* ==== components.136.css ==== */
.modal{box-shadow:var(--shadow-lg)}

.menu{box-shadow:var(--shadow-md)}
/* ==== layout.043.css ==== */
/* ---------- 2. Боковая панель -------------------------------- */
/* Панель отступает на второй план: почти белый фон, единственная
   вертикальная граница, никаких заливок-«кнопок» у пунктов.
   Активный пункт отмечен мягкой акцентной подложкой — по одному
   такому пункту на экран, поэтому фиолетовый здесь уместен. */
#sidebar{background:var(--chrome-2);border-right:1px solid var(--line-2)}
/* ==== utilities.182.css ==== */
.side-head{padding:0 14px;height:var(--topbar-h)}

.brand-name{font-size:var(--t-h3);font-weight:650;letter-spacing:-.02em}

.brand-mark{width:24px;height:24px}

.side-create{margin:4px 12px 10px}
/* ==== components.137.css ==== */
.btn-create{height:36px;font-size:var(--t-body);font-weight:600;border-radius:var(--r-md);gap:8px}

.btn-create svg{width:16px;height:16px}
/* ==== layout.044.css ==== */
.side-nav{padding:0 8px 16px}

.nav-item,.proj-item{
  padding:6px 9px;border-radius:var(--r-md);font-size:var(--t-body);
  font-weight:450;color:var(--ink-2);gap:10px;min-height:32px;
}

.nav-item svg{width:16px;height:16px}

.nav-item:hover,.proj-item:hover{background:var(--surface-3);color:var(--ink)}

.nav-item.active,.proj-item.active{background:var(--accent-soft);color:var(--accent-700);font-weight:600}

.nav-item.active svg,.proj-item.active svg{color:var(--accent)}

[data-theme="dark"] .nav-item.active,[data-theme="dark"] .proj-item.active{background:var(--accent-soft);color:var(--accent-600)}

/* Заголовок группы — служебная подпись, а не третий уровень
   заголовков: мельче, тише, с воздухом сверху вместо линейки. */
.nav-label{
  font-size:var(--t-xs);font-weight:600;color:var(--faint);
  letter-spacing:.01em;padding:16px 9px 4px;
}

.nav-item .badge{
  background:transparent;color:var(--faint);font-weight:600;
  font-size:var(--t-xs);min-width:auto;height:auto;padding:0;
}

.nav-item.active .badge{background:transparent;color:var(--accent-700)}
/* ==== utilities.183.css ==== */
.side-foot{border-top:1px solid var(--line-2);padding:8px}

.side-plan{display:flex;align-items:center;justify-content:space-between;gap:8px;
  margin:6px 10px 0;padding:7px 10px;border-radius:var(--r-md);
  background:var(--surface-2);cursor:pointer;transition:background var(--dur-instant)}

.side-plan:hover{background:var(--surface-3)}

.side-plan:focus-visible{outline:none;box-shadow:var(--ring)}

.side-plan-name{font-size:var(--t-xs);font-weight:600;color:var(--muted);text-transform:uppercase;letter-spacing:.02em}

.side-plan-cta{font-size:var(--t-xs);font-weight:700;color:var(--accent-700)}

[data-theme="dark"] .side-plan-cta{color:var(--accent-600)}

.collapsed .side-plan{margin:6px 6px 0;padding:7px 0;justify-content:center}

.collapsed .side-plan-name,.collapsed .side-plan-cta{display:none}

.side-plan svg{flex-shrink:0;color:var(--accent-700)}

[data-theme="dark"] .side-plan svg{color:var(--accent-600)}

.proj-dot,.proj-item .proj-dot{width:9px;height:9px;border-radius:3px;box-shadow:none}

/* ---------- 3. Верхняя навигация ----------------------------- */
/* Рабочая область и шапка теперь одного цвета — граница снизу
   отделяет их сама, без перепада заливки. */
#topbar{background:var(--canvas);border-bottom:1px solid var(--line-2);padding:0 var(--gutter) 0 18px;gap:12px}
/* ==== components.138.css ==== */
.tb-search input{
  height:32px;background:var(--surface-2);border:1px solid transparent;
  border-radius:var(--r-md);font-size:var(--t-sm);padding:0 12px 0 34px;
}

.tb-search input:hover{background:var(--surface-3);border-color:transparent}

.tb-search input:focus{background:var(--surface);border-color:var(--accent);box-shadow:var(--ring)}
/* ==== features.054.css ==== */
.tb-search svg{top:7px;left:10px;width:15px;height:15px;color:var(--faint)}
/* ==== utilities.184.css ==== */
.tb-icon{width:32px;height:32px;border-radius:var(--r-md);color:var(--faint)}

.tb-icon svg{width:17px;height:17px}

.tb-icon:hover{background:var(--surface-3);color:var(--ink-2)}

/* «Создать» присутствует дважды — в боковой панели и в шапке, и обе
   кнопки были залиты сплошным акцентом. Два одинаковых ярких пятна
   для одного и того же действия в двадцати сантиметрах друг от друга
   не удваивают заметность, а обесценивают её: раз всё выделено,
   выделено ничто. Главной остаётся кнопка в боковой панели —
   постоянное место, куда приходят осознанно; дубль в шапке переведён
   в мягкий вариант акцента. Он по-прежнему явно акцентный и находится
   там же, где был, но сплошная заливка на экране одна. */
.tb-create,.tb-create-caret{
  height:32px;background:var(--accent-soft);color:var(--accent-700);
}

.tb-create:hover,.tb-create-caret:hover{background:var(--accent-line)}

[data-theme="dark"] .tb-create,[data-theme="dark"] .tb-create-caret{color:var(--accent-600)}

.tb-create{padding:0 12px 0 8px;font-size:var(--t-sm);border-radius:var(--r-md) 0 0 var(--r-md)}

.tb-create-caret{border-radius:0 var(--r-md) var(--r-md) 0;width:24px;border-left:1px solid var(--accent-line)}

.tb-create-ic{width:18px;height:18px;border-radius:var(--r-xs);background:transparent}

[data-theme="dark"] .tb-create-ic{background:transparent}

/* Хлебная крошка в шапке (crumbFor()) — найдена и оставлена не
   используемой сознательно, а не по недосмотру: функция вычисляет
   иконку+название текущего раздела, но результат нигде не
   подставляется в разметку renderTopbar() (переменная реально не
   применялась — мёртвый расчёт на каждый рендер, теперь убран).
   Название раздела уже показано крупным заголовком в самом контенте
   (.page-head/.ph-title на странице проекта и аналоги на остальных
   экранах) — второй, мелкий дубль в шапке был бы тем самым
   повторением одного и того же в двух местах, от которого избавлялись
   в этом же разделе редизайна (см. соседние правки «Создать»/иконка
   профиля/лого выше). Функция crumbFor() и стили .tb-crumb ниже не
   удалены — они не влияют на текущий рендер, но могут понадобиться,
   если для узких экранов/breadcrumbs понадобится другое решение. */
.tb-crumb{min-width:0;max-width:clamp(80px,28vw - 136px,300px);overflow:hidden;flex-shrink:1}

.tb-crumb .c-icon{width:20px;height:20px;border-radius:var(--r-sm)}

/* ---------- 4. Заголовок страницы ---------------------------- */
/* Титул уменьшен и облегчён по начертанию (700 → 650): при
   13-пиксельном основном тексте прежние 28px/700 выглядели
   несоразмерно и съедали верх экрана. Воздух вокруг увеличен —
   заголовок отделяется паузой, а не кеглем. */
.page-head{padding:24px var(--gutter) 0}

.page-title,.ph-title{font-size:var(--t-display);font-weight:650;letter-spacing:-.02em;line-height:1.25}

.page-sub,.ph-desc{font-size:var(--t-sm);color:var(--muted);margin-top:6px;line-height:1.55}

.ph-eyebrow{font-size:var(--t-xs);color:var(--faint);font-weight:500;margin-bottom:6px}

.ph-emoji{width:32px;height:32px;border-radius:var(--r-md);font-size:var(--t-h2);box-shadow:none;border:1px solid var(--line-2)}

.ph-title{gap:10px}

.ph-actions{gap:6px;padding-top:2px}
/* ==== components.139.css ==== */
.avatar-stack .avatar{border:2px solid var(--canvas);margin-left:-7px}

.avatar-add{width:26px;height:26px;border-width:1px;margin-left:-7px}

/* ---------- 5. Вкладки --------------------------------------- */
/* Активная вкладка отмечена подчёркиванием и цветом текста —
   двух признаков достаточно, заливка не нужна. */
.tabs{margin-top:18px;gap:0;border-bottom:1px solid var(--line-2)}

.tab{
  padding:7px 12px 10px;font-size:var(--t-sm);font-weight:550;
  color:var(--muted);border-radius:0;border-bottom-width:2px;
}

.tab svg{width:15px;height:15px;color:var(--faint)}

.tab:hover{color:var(--ink);background:transparent}

.tab.active{color:var(--accent-700);font-weight:600;border-bottom-color:var(--accent)}

[data-theme="dark"] .tab.active{color:var(--accent-600)}
/* ==== features.055.css ==== */
/* ---------- 6. Панель инструментов --------------------------- */
/* Фильтры — вспомогательный ряд, поэтому он тише содержимого:
   мелкий кегль, нейтральные чипы, тонкая нижняя граница. */
.view-toolbar{padding:9px var(--gutter);border-bottom:1px solid var(--line-2);gap:6px}
/* ==== utilities.185.css ==== */
.chip{
  height:var(--ctl-h-sm);padding:0 10px;font-size:var(--t-sm);font-weight:500;
  border-radius:var(--r-md);background:transparent;border:1px solid var(--line);color:var(--ink-2);
}

.chip:hover{background:var(--surface-2);border-color:var(--line-3)}

.chip svg{width:13px;height:13px}

.chip.on{background:var(--accent-soft);border-color:var(--accent-line);color:var(--accent-700);font-weight:600}

/* Тёмная тема задавала чипу собственную заливку правилом с более
   высокой специфичностью — без такого же парного правила чип остался
   бы единственным элементом панели с фоном, выбиваясь из ряда. */
[data-theme="dark"] .chip{background:transparent}

[data-theme="dark"] .chip:hover{background:var(--surface-2)}

[data-theme="dark"] .chip.on{background:var(--accent-soft);color:var(--accent-600)}

.chip-add{background:var(--accent);border-color:var(--accent);color:var(--accent-fg)}

.chip-add:hover{background:var(--accent-600);border-color:var(--accent-600)}

[data-theme="dark"] .chip-add{background:var(--accent)}
/* ==== components.140.css ==== */
/* ---------- 7. Кнопки ---------------------------------------- */
/* Одна заметная кнопка на экран. Главное действие — сплошной
   акцент без градиента и блика; всё прочее — нейтральная
   обводка. Так «Создать» видно сразу, а ряд второстепенных
   кнопок не притворяется таким же важным. */
.btn{border-radius:var(--r-md);font-weight:600;font-size:var(--t-sm);padding:0 13px;gap:6px}

.btn svg{width:15px;height:15px}

.btn-primary{background:var(--accent);color:var(--accent-fg)}

.btn-primary:hover{background:var(--accent-600)}

.btn-ghost{background:var(--surface);border:1px solid var(--line);color:var(--ink-2)}

.btn-ghost:hover{background:var(--surface-2);border-color:var(--line-3);color:var(--ink)}

.btn-soft{background:var(--accent-soft);color:var(--accent-700)}

.btn-sm{height:var(--ctl-h-sm);font-size:var(--t-sm);padding:0 10px}

.btn-danger{background:var(--danger);border-color:var(--danger)}

/* ---------- 8. Поля ввода ------------------------------------ */
/* Поле — белое с тонкой границей, а не серая «ванночка». Серая
   заливка на светлом фоне читается как выключенный элемент;
   белое поле с границей честнее показывает, что сюда пишут. */
.form-input{
  height:var(--ctl-h-lg);border:1px solid var(--line);border-radius:var(--r-md);
  background:var(--surface);font-size:var(--t-body);padding:0 12px;
}

.form-input:hover{border-color:var(--line-3)}

.form-input:focus{border-color:var(--accent);box-shadow:var(--ring);background:var(--surface)}

.form-lbl{font-size:var(--t-sm);font-weight:550;color:var(--ink-2)}

.add-section-input{border-radius:var(--r-md);font-weight:500}

/* ---------- 9. Выпадающие меню ------------------------------- */
.menu{border-radius:var(--r-lg);padding:5px;border:1px solid var(--line)}

.menu-item{border-radius:var(--r-sm);padding:7px 9px;font-size:var(--t-sm);font-weight:450;gap:9px}

.menu-item svg{width:15px;height:15px}

.menu-item:hover{background:var(--surface-2);color:var(--ink)}

.menu-head{font-size:var(--t-xs);font-weight:600;color:var(--faint);padding:8px 9px 4px}

.menu-sep{background:var(--line-2);margin:5px 4px}
/* ==== utilities.186.css ==== */
.tb-lang-pop{border-radius:var(--r-lg);box-shadow:var(--shadow-md)}

.lang-opt{border-radius:var(--r-sm);font-size:var(--t-sm)}

.lang-opt:hover{background:var(--surface-2)}
/* ==== components.141.css ==== */
/* ---------- 10. Карточки ------------------------------------- */
/* Карточка — лист на столе, а не кирпич: одна граница, ровный
   умеренный угол, состояние наведения через фон и границу. */
.card{border:1px solid var(--line);border-radius:var(--r-lg);padding:11px 12px}

.card-title{font-size:var(--t-sm);font-weight:500;line-height:1.45}

/* Метка на карточке доски и метка в строке списка — одна и та же
   сущность в двух представлениях; радиус у них был разный (4 и 6px),
   что при переключении «Список ↔ Доска» читалось как смена стиля. */
.card-tag{font-size:var(--t-micro);font-weight:550;border-radius:var(--r-sm);padding:2px 7px;letter-spacing:0}

.card-meta,.card-foot{margin-top:8px;gap:6px}
/* ==== features.056.css ==== */
.board-col{background:var(--well);border:1px solid var(--line-2);border-radius:var(--r-lg)}
/* ==== utilities.187.css ==== */
.bc-head{padding:12px 12px 8px;gap:8px}

.bc-title{font-size:var(--t-sm);font-weight:600}

.bc-count{font-size:var(--t-xs);background:transparent;color:var(--faint);padding:0}

.bc-body{padding:2px 8px 8px;gap:6px}
/* ==== components.142.css ==== */
.board-addcol button{border-radius:var(--r-lg);border-width:1px;font-size:var(--t-sm);font-weight:550}
/* ==== utilities.188.css ==== */
/* ---------- 11. Списки и таблицы ----------------------------- */
/* Разлиновка ослаблена до почти незаметной, наведение — только
   фон без тени и «подпрыгивания». В длинном списке важен ритм
   строк, а не рамка вокруг каждой. */
.list-colhead{border-bottom:1px solid var(--line-2);padding-bottom:8px}

.list-colhead .ch{font-size:var(--t-xs);font-weight:500;color:var(--faint)}
/* ==== features.057.css ==== */
.task-row{border-bottom:1px solid var(--line-2);border-radius:var(--r-sm);min-height:44px}

.task-row:hover{background:var(--surface-2);box-shadow:none;border-bottom-color:var(--line-2)}

[data-theme="dark"] .task-row:hover{background:var(--surface-2)}

.task-name{font-size:var(--t-sm);font-weight:450}

.task-check{width:17px;height:17px;border-width:1.5px}
/* ==== utilities.189.css ==== */
.section-head{padding:16px 12px 6px}

.section-title{font-size:var(--t-sm);font-weight:650;letter-spacing:-.01em}

.section-count{background:transparent;color:var(--faint);padding:0;font-size:var(--t-xs)}

.add-row{font-size:var(--t-sm);border-radius:var(--r-sm)}

.due-pill{font-size:var(--t-xs);font-weight:500;border-radius:var(--r-xs);padding:2px 7px}

.cell-assignee .nm{font-size:var(--t-sm);color:var(--muted)}

.cell-empty{width:24px;height:24px;border-width:1px}

/* ---------- 12. Метки и статусы ------------------------------ */
/* Плашка не должна быть плотнее текста, который описывает.
   Обычное начертание, спокойный тинт, умеренный угол. */
.prio-tag,.status-tag{
  font-size:var(--t-xs);font-weight:500;padding:2px 8px;
  border-radius:var(--r-sm);letter-spacing:0;
}

.prio-tag .pd{width:5px;height:5px}
/* ==== components.143.css ==== */
/* ---------- 13. Модальные окна ------------------------------- */
/* Прежние 22px скругления на окне шириной 500px — самый
   узнаваемый признак шаблона. Угол приведён к общей шкале,
   подложка осветлена, разделители тоньше. */
.modal{border-radius:var(--r-2xl);border:1px solid var(--line)}

.modal-back{background:rgba(24,26,34,.36);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px)}

.modal-head{padding:20px 22px 2px}

.modal-title{font-size:var(--t-h2);font-weight:650;letter-spacing:-.015em}

.modal-x{width:28px;height:28px;border-radius:var(--r-md);color:var(--faint)}

.modal-x:hover{background:var(--surface-2);color:var(--ink)}

.modal-body{padding:14px 22px 20px}

.modal-foot{padding:13px 22px;border-top:1px solid var(--line-2);background:var(--surface-2);gap:8px}

.modal-sub{font-size:var(--t-xs);font-weight:600;color:var(--faint)}

/* 2.315.0: на сенсорных экранах крестик окна — полноценная цель 44px.
   Значок остаётся прежнего размера, растёт только область нажатия
   (increase hit area), поэтому вид окна на телефоне не меняется. */
@media (hover: none) and (pointer: coarse) {
  .modal-x { width: 44px; height: 44px; margin-right: -8px; }
  .modal-foot .btn, .modal-body .btn { min-height: 44px; }
}
/* ==== utilities.190.css ==== */
/* ---------- 14. Пустые состояния ----------------------------- */
/* Пустой экран — не повод для крупной графики: подпись объясняет,
   кнопка предлагает действие, значок лишь обозначает место. */
.empty-state{padding:56px 20px;color:var(--muted)}

.empty-ic{
  width:44px;height:44px;margin:0 auto 14px;border-radius:var(--r-xl);
  background:var(--surface-2);border:1px solid var(--line-2);color:var(--faint);
}

.empty-ic svg{width:20px;height:20px}

.empty-title{font-size:var(--t-h3);font-weight:650;letter-spacing:-.01em;margin-bottom:5px}

.empty-desc{font-size:var(--t-sm);color:var(--muted);max-width:340px;margin:0 auto 16px;line-height:1.6}

.empty-cta{margin-top:14px}
/* ==== components.144.css ==== */
/* ---------- 15. Общая консистентность ------------------------ */
/* Сквозные правила: одинаковый угол у всего, что нажимают или
   заполняют, и единая тонкая граница у контейнеров — чтобы
   элементы, написанные в разное время и в разных местах файла,
   всё равно выглядели частями одной системы. */
input,select,textarea,button{font-family:var(--sans)}

.avatar{box-shadow:none}
/* ==== layout.045.css ==== */
.sh-actions button,.bc-head .bc-menu,.card-more,.side-collapse,.nav-label .add{border-radius:var(--r-sm);color:var(--faint)}

.sh-actions button:hover,.bc-head .bc-menu:hover,.card-more:hover,.side-collapse:hover,.nav-label .add:hover{background:var(--surface-3);color:var(--ink-2)}

.cal-nav button{border-radius:var(--r-md);box-shadow:none;border-color:var(--line)}
/* ==== utilities.191.css ==== */
.cal-title{font-size:var(--t-h3);font-weight:650}
/* ==== components.145.css ==== */
.ai-chat-input{border-radius:var(--r-md)}
/* ==== utilities.192.css ==== */
/* ---------- 16. Проход консистентности ----------------------- */
/* Эти размеры были вписаны числом мимо шкалы и остались от
   прежней, более крупной типографики: 32px у показателя, 26px у
   приветствия, 25px у названия задачи. Рядом с уменьшенным
   заголовком страницы (22px) они выглядели бы главнее самого
   раздела — иерархия перевернулась бы. Приведены к шкале,
   соотношения между ступенями сохранены. */
.stat-value{font-size:26px;font-weight:650;letter-spacing:-.025em;line-height:1.1}

.ov-stat-n,.wl-sum-n{font-size:20px;font-weight:650;letter-spacing:-.02em}

.home-greet{font-size:var(--t-display);font-weight:650;letter-spacing:-.02em}

.prof-name,.focus-title{font-size:var(--t-h1);font-weight:650;letter-spacing:-.02em}

.prof-ava{width:72px;height:72px;font-size:24px;font-weight:650}

.focus-timer span{font-size:30px;font-weight:600}
/* ==== features.058.css ==== */
.guide-doc .rich-h1,.guide-doc h1{font-size:var(--t-h1);font-weight:650;letter-spacing:-.02em;margin:0 0 14px}
/* ==== layout.046.css ==== */
/* Название задачи в панели — заголовок карточки, а не обложка:
   вровень со ступенью h1, не крупнее заголовка самого раздела. */
.panel-name{font-size:var(--t-h1);font-weight:650;letter-spacing:-.02em;line-height:1.3}
/* ==== utilities.193.css ==== */
@media(max-width:768px){
  .stat-value{font-size:var(--t-display)}
  .prof-ava{width:60px;height:60px;font-size:20px}
  .home-greet{font-size:var(--t-h1)}
}
/* ==== layout.047.css ==== */
/* ============================================================
   17. SIDEBAR — целевой редизайн навигации
   ------------------------------------------------------------
   Отдельный, финальный блок: он идёт последним в каскаде и
   сознательно уточняет разделы 2 («Боковая панель») и правила
   групп/подгрупп выше — так весь язык боковой панели снова виден
   одним куском, а не размазан правкой на месте. Ничего в разметке,
   в data-act/data-view атрибутах и в обработчиках не меняется —
   только то, как эти же самые элементы выглядят.

   Три решения, из которых выведено остальное:

   1. Единая строка. Все навигационные ряды — обычный пункт,
      строка проекта, заголовок папки, подзаголовок подпапки —
      выровнены по одной сетке высот и одному левому отступу.
      Раньше высота держалась на padding и «плавала» от паддингов
      расставленных в разных местах; здесь — явная высота и
      единственный источник горизонтального отступа.

   2. Активность — это не кнопка. Прежний «active»-фон был мягким,
      но всё ещё читался как заливка на всю строку с усиленным
      начертанием. Здесь фон почти не виден, вес текста не
      меняется, а единственный уверенный сигнал «вы здесь» —
      цвет иконки/текста и тонкая цветная полоса слева, приклеенная
      к краю строки, а не к её скруглённым углам.

   3. Три уровня, а не один общий список. Личные пункты (Главная,
      Мои задачи, Входящие) — начало координат, без подписи.
      Заголовок группы («Избранное», «Проекты», …) — служебный
      микро-лейбл, тише всего на панели. Строка внутри группы —
      обычный вес. Разделитель-линия — ровно один, там, где
      начинается пользовательский контент (проекты), потому что
      это единственная граница, которая структурно важна; все
      остальные группы отделены только воздухом.
   ============================================================ */

/* --- Общая сетка отступов ------------------------------------ */
/* Один отступ для всего: пунктов, названий групп, папок. Раньше
   заголовок группы (12px) и сам пункт (9px) расходились на
   несколько пикселей — незаметная, но подтачивающая ощущение
   мелочь, из-за которой левый край панели выглядел не выровненным. */
#sidebar{--side-x:10px;--side-row-h:30px}
/* ==== utilities.194.css ==== */
/* --- Верхняя часть: компактно и без лишнего веса -------------- */
.side-head{height:50px;padding:0 12px 0 12px;gap:8px}

.brand{gap:8px}

.brand-mark{width:20px;height:20px}

.brand-name{font-size:var(--t-h3);font-weight:600;letter-spacing:-.01em}

.side-collapse{width:24px;height:24px}

.side-collapse svg{width:14px;height:14px}

.side-create{margin:0 var(--side-x) 8px}
/* ==== components.146.css ==== */
.btn-create{
  height:32px;font-size:var(--t-sm);font-weight:600;
  border-radius:var(--r-md);gap:7px;
  /* Раньше это была вторая сплошная заливка акцентом на панели —
     решение «одна яркая заливка на экран» уже принято на уровне
     верхней панели (см. .tb-create), здесь та же логика: основная
     команда «Создать» живёт в сайдбаре и остаётся сплошной, потому
     что это единственное такое место на панели, не в паре с чем-то
     ещё. */
  box-shadow:none;
}

.btn-create svg{width:15px;height:15px}
/* ==== layout.048.css ==== */
/* --- Навигация: общая сетка ------------------------------------ */
.side-nav{padding:2px 8px 12px}

/* --- Пункт меню и строка проекта: одна высота, один отступ ----- */
.nav-item,.proj-item{
  height:var(--side-row-h);min-height:var(--side-row-h);
  padding:0 8px;border-radius:var(--r-sm);
  font-size:var(--t-sm);font-weight:450;
  color:var(--ink-2);gap:9px;
  position:relative;
}

.nav-item svg,.proj-item svg{width:15px;height:15px;color:var(--faint)}

.nav-item:hover,.proj-item:hover{background:var(--surface-3);color:var(--ink)}

.nav-item:hover svg,.proj-item:hover svg{color:var(--muted)}

.nav-item:focus-visible,.proj-item:focus-visible{outline:none;box-shadow:var(--ring)}
/* ==== utilities.195.css ==== */
/* Тот же кольцевой фокус — на остальных интерактивных div-ах панели,
   которые раньше не получали фокус вовсе (см. правку доступности
   клавиатуры в скрипте): заголовки групп, лого-ссылка на «Домой». */
.grp-head:focus-visible,.subgrp-head:focus-visible,.brand:focus-visible{outline:none;box-shadow:var(--ring)}
/* ==== layout.049.css ==== */
/* Активность: почти без фона, вес текста не меняется — заметна
   только по цвету и по тонкой полосе у самого края строки. Полоса
   рисуется отдельным слоем внутри паддинга ряда (не выходит за
   границу .side-nav), поэтому не обрезается прокруткой. */
.nav-item.active,.proj-item.active{
  background:var(--accent-soft);color:var(--accent-700);
  font-weight:500;box-shadow:none;
}

.nav-item.active::before,.proj-item.active::before{
  content:'';position:absolute;left:0;top:6px;bottom:6px;width:2.5px;
  border-radius:var(--r-pill);background:var(--accent);
}

.nav-item.active svg,.proj-item.active svg{color:var(--accent)}

[data-theme="dark"] .nav-item.active,[data-theme="dark"] .proj-item.active{color:var(--accent-600)}
/* ==== utilities.196.css ==== */
/* Открытый проект — тот же принцип активности, плюс лёгкое кольцо
   на цветной точке: маленький, узнаваемый сигнал «этот проект
   сейчас открыт», без изменения размера самой строки. */
.proj-item.active .proj-dot{box-shadow:0 0 0 2px var(--canvas),0 0 0 3px var(--accent-line)}
/* ==== layout.050.css ==== */
/* Счётчик непрочитанного — тихий по умолчанию, не плашка с фоном:
   цифра рядом с названием пункта, не отдельный цветной объект. */
.nav-item .badge{
  background:transparent;color:var(--faint);font-weight:600;
  font-size:var(--t-xs);min-width:auto;height:auto;padding:0;
  font-variant-numeric:tabular-nums;
}

.nav-item.active .badge{background:transparent;color:var(--accent-700)}
/* ==== utilities.197.css ==== */
/* --- Заголовки групп: тише всего на панели --------------------- */
.side-group-title{
  padding:14px 8px 5px;font-size:var(--t-micro);font-weight:600;
  color:var(--faint);letter-spacing:.02em;
}

.side-group:first-child .side-group-title{padding-top:2px}

.side-group-add{width:18px;height:18px;color:var(--faint)}

.side-group-add:hover{background:var(--surface-3);color:var(--ink-2)}
/* ==== features.059.css ==== */
/* Единственная содержательная граница на панели: здесь начинается
   пользовательский контент (проекты), а не ещё один системный
   раздел, поэтому только тут линия оправдана как ориентир. */
.side-group-projects{border-top:1px solid var(--line-2);margin-top:4px;padding-top:6px}
/* ==== utilities.198.css ==== */
/* --- Проекты: папки и вложенные строки --------------------------
   Папка (grp-head) — служебный контейнер: чуть плотнее по весу,
   приглушённый цвет, каретка. Строка проекта внутри — обычный вес,
   свой цветной индикатор вместо папочной иконки. Разница веса и
   цвета между ними и есть подсказка «это группа, а это — сам
   проект», без дополнительной графики. */
.grp-head{height:var(--side-row-h);padding:0 8px;border-radius:var(--r-sm);gap:7px;font-size:var(--t-sm);font-weight:550;color:var(--muted)}

.grp-head:hover{background:var(--surface-3);color:var(--ink-2)}

.grp-caret svg{width:12px;height:12px}

.grp-emoji{font-size:var(--t-sm)}

.grp-count{background:transparent;color:var(--faint);padding:0;font-size:var(--t-micro)}
/* ==== components.147.css ==== */
.grp-menu{width:20px;height:20px}
/* ==== utilities.199.css ==== */
.proj-item-quick{width:18px;height:18px}

.grp-body{padding-left:8px}

.subgrp-head{height:26px;padding:0 8px;gap:6px;font-size:var(--t-sm);color:var(--faint)}

.subgrp-body{padding-left:8px;border-left:1px solid var(--line-2);margin-left:7px}

.proj-dot{width:7px;height:7px;border-radius:2px}
/* ==== layout.051.css ==== */
/* --- Пространство и утилитарное: без границ, только воздух ----- */
/* Portfolios/People/Reports и Trash/Settings — второстепенные по
   отношению к «Проектам», но это два равноправных системных
   раздела, не пользовательский контент, поэтому между ними и над
   ними — только пауза по вертикали, без новой линии: ещё один
   разделитель здесь уже был бы избыточным. */
.side-nav .side-group+.side-group{margin-top:2px}
/* ==== utilities.200.css ==== */
/* --- Нижняя часть: профиль, явно отдельная зона ----------------- */
/* Лёгкий контраст поверхности плюс верхняя граница — подвал читается
   как самостоятельная зона панели, а не последний пункт списка. */
.side-foot{
  border-top:1px solid var(--line-2);padding:8px;
  background:var(--surface-2);flex-shrink:0;
}

[data-theme="dark"] .side-foot{background:var(--chrome-2)}

.side-plan{background:var(--surface);margin:6px 8px 0}

.side-plan:hover{background:var(--surface-3)}

[data-theme="dark"] .side-plan{background:var(--chrome-2)}

.user-chip{padding:6px 6px;border-radius:var(--r-md);gap:8px}

.user-chip:hover{background:var(--surface-3)}

.user-chip:focus-visible{outline:none;box-shadow:var(--ring)}

.user-chip .nm{font-size:var(--t-sm);font-weight:600}

.user-chip .sub{font-size:var(--t-xs);color:var(--faint)}
/* ==== layout.052.css ==== */
/* --- Свёрнутое состояние: та же система, только без подписей ---- */
.collapsed .nav-item,.collapsed .proj-item{justify-content:center;padding:0}

.collapsed .nav-item.active::before,.collapsed .proj-item.active::before{left:2px}

/* --- Disabled: пункт виден, но временно недоступен (например,
   раздел, требующий прав, которых у текущей роли ещё нет) — общий
   визуальный язык на случай будущего использования, тот же принцип,
   что уже применён к .btn:disabled (приглушение + курсор + никакой
   реакции на события), просто адаптированный под div-based пункты
   навигации, у которых нет нативного атрибута disabled. */
.nav-item[aria-disabled="true"],.proj-item[aria-disabled="true"]{
  opacity:.45;cursor:not-allowed;pointer-events:none;
}
/* ==== utilities.201.css ==== */
/* --- Мобильный сайдбар: тот же язык, крупнее цели под палец ----- */
/* Плотная сетка удобна на трекпаде и мыши, но на телефоне ряд
   в 30px слишком узкая мишень — здесь та же система токенов,
   только высота и внутренний отступ увеличены под палец, а не
   переизобретены заново. */
@media(max-width:768px){
  #sidebar{--side-row-h:44px}
  .side-head{height:54px}
  .nav-item,.proj-item,.grp-head{padding:0 10px}
  .nav-item svg,.proj-item svg{width:17px;height:17px}
  .side-nav{padding:4px 10px 14px}
  .subgrp-head{height:36px}
  .user-chip{padding:8px 6px}
  /* Быстрые действия («…» проекта/группы) наведением недоступны на
     тач-экране — без hover они были бы видны только по случайному
     :focus-visible. На мобильном показываем сразу, приглушённо, как
     обычный, всегда доступный элемент строки, а не скрытую находку. */
  .grp-menu,.proj-item-quick{opacity:.55}
  .grp-menu,.proj-item-quick{width:26px;height:26px}
}

/* ============================================================
   18. РАБОЧИЕ ОБЛАСТИ — списки, Kanban, панель задачи
   ------------------------------------------------------------
   Финальный уточняющий блок для экранов, где проходит основная
   работа: список задач, доска, страница проекта, панель задачи.
   Как и раздел 17, это чистые уточнения поверх более ранних
   правил (в первую очередь раздела «10–13» общего редизайна) —
   разметка и обработчики не менялись.

   Перед правкой каждый из этих экранов был собран в изолированном
   превью с реальными классами разметки и отрисован в headless
   Chrome, чтобы отличать настоящие находки от предположений. Ниже —
   только то, что подтвердилось на скриншотах.

   Главный принцип, вынесенный в заголовок задачи: контент — главный
   элемент экрана. Название задачи, текст описания, содержимое
   карточки должны быть первым, что считывает взгляд; чекбоксы,
   иконки-обрамление, счётчики и второстепенные свойства — вторым.
   ============================================================ */

/* --- Список задач: чуть больше воздуха между секциями --------- */
.list-wrap{padding:14px var(--gutter) 64px}
/* ==== features.060.css ==== */
/* --- Kanban: колонки легче, карточки компактнее ---------------- */
.board-wrap{padding:18px var(--gutter) 44px}
/* ==== utilities.202.css ==== */
.bc-body{gap:7px}

/* Заголовок колонки — служебный, но не второстепенный: он должен
   опознаваться раньше любой карточки внутри неё. Более ранний слой
   редизайна (раздел «10. Карточки») по инерции унифицировал вес
   заголовка колонки с обычным текстом (600), из-за чего на скрине
   колонка «В работе» и заголовок задачи внутри неё читались почти
   одним весом — тень иерархии, а не сама иерархия. Здесь она
   восстановлена явно: заметнее по начертанию, без увеличения кегля,
   то есть без «громоздкости». */
.bc-title{font-weight:700;letter-spacing:-.012em}
/* ==== components.148.css ==== */
.card{padding:10px 12px}

.card-meta,.card-foot{margin-top:7px;gap:5px}

/* --- Вкладки внутри панели задачи: тот же язык, что у вкладок
   страницы -------------------------------------------------------
   На скриншоте панели активная вкладка «Обсуждение» подчёркивалась
   тёмно-серым (var(--ink)), тогда как вкладки страницы проекта
   (Список/Доска/Календарь) — акцентным цветом. Один и тот же
   элемент интерфейса — вкладка — вёл себя по-разному в двух местах
   приложения; это и есть расхождение дизайн-системы, которое просили
   найти и устранить. Приведено к общему языку вкладок. */
.cm-tab.active{color:var(--accent-700);border-bottom-color:var(--accent)}

[data-theme="dark"] .cm-tab.active{color:var(--accent-600)}
/* ==== utilities.203.css ==== */
/* --- Проверка консистентности между представлениями ------------
   Ниже — не новые правила, а фиксация того, что уже подтверждено
   визуально и оставлено без изменений, чтобы следующая правка не
   разошлась с этим списком случайно:
   • Активное/выбранное состояние везде — один и тот же токен
     var(--accent): .row-sel.on, .card-sel.on, .card-selected,
     .nav-item.active, .proj-item.active, .tab.active, .chip.on.
   • Пустые ячейки (due/priority/status/assignee) — один класс
     .cell-empty, один размер, один стиль пунктирной границы
     во всех трёх представлениях (список, доска, панель задачи).
   • Наведение на строку/карточку/пункт меню — везде нейтральный
     var(--surface-2)/var(--surface-3), без акцентной подсветки;
     акцент зарезервирован только за «выбрано» и «активно».
   • Радиус: r-sm/r-md/r-lg используются по одной и той же логике
     во всех рабочих экранах — мелкие элементы управления (r-sm),
     карточки и поля (r-md/r-lg), ничего сверх шкалы. */

/* ============================================================
   19. МОДАЛЬНЫЕ ОКНА, ФОРМЫ, DROPDOWN И POPOVER — унификация
   ------------------------------------------------------------
   Пройдена вся система «временных поверхностей» приложения:
   модальные окна, формы внутри них, выпадающие меню, попапы
   выбора (люди, эмодзи, язык интерфейса) и боковая панель деталей
   задачи. Ниже — только реальные расхождения, найденные построчным
   чтением CSS-правил этих компонентов и сверкой их вычисленных
   значений (высота, радиус, тень, blur) друг с другом. Каждый пункт
   указывает конкретное prежнее значение и что с ним не так.
   ============================================================ */

/* --- Поля ввода: одна высота без исключений --------------------
   .auth-in (поля на экране входа/регистрации) задавали высоту
   числом — 38px, — тогда как .form-input (те же по смыслу поля
   внутри модальных окон) используют токен var(--ctl-h-lg) = 40px.
   Разницы 2px не видно на глаз в отдельности, но на экране входа
   .auth-in стоит в одной колонке с .auth-btn, который ЭТОТ ЖЕ
   токен уже использует, — и тогда 2px становятся заметны как
   лёгкая нестыковка высоты между соседними элементами одной формы.
   Радиус был на var(--r-sm), хотя это по смыслу — форм-контрол,
   а не мелкий служебный элемент; переведён на var(--r-ctl)
   (сейчас то же самое число, 6px, но правильный по смыслу токен,
   чтобы оба значения менялись синхronно в будущем). */
.auth-in{height:var(--ctl-h-lg);border-radius:var(--r-ctl)}

/* --- Popover выбора людей: та же тень, что у обычного меню ------
   .pp-pop (попап «Добавить участника») делит объявление тени с
   .menu в общем правиле, но .menu впоследствии был облегчён (раздел
   9 этого же слоя, box-shadow:var(--shadow-md)) — а .pp-pop эту
   правку не унаследовал и остался на прежней, более тяжёлой паре
   shadow-lg + внутренний блик. Один и тот же тип поверхности
   («всплывающий выбор из списка») выглядел по-разному в зависимости
   от того, кого выбираешь — участника задачи или пункт меню.
   Приведено к одной, более лёгкой тени. */
.pp-pop{box-shadow:var(--shadow-md)}
/* ==== components.149.css ==== */
/* --- Затемнение и блюр фона: одно и то же значение везде --------
   Три разных перекрытия — общий .overlay, .modal-back и оверлей
   командной палитры .cmdk-overlay — задавали три чуть разных
   значения blur (3px / 3px / 4px) и непрозрачности (.36/.36/.4).
   Разница на глаз почти неразличима, но раз это один и тот же
   визуальный приём (притушить фон под всплывающей поверхностью),
   у него должно быть одно число, а не три случайно близких. */
.overlay,.modal-back,.cmdk-overlay{
  background:rgba(20,21,28,.4);
  backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);
}
/* ==== layout.053.css ==== */
/* --- Верхняя панель деталей задачи: было настоящее стекло -------
   .panel-top — приклеенная при прокрутке шапка панели задачи
   (кнопки «Фокус» / «Отметить готовой» / закрыть) — использовала
   blur(12px). Это в 3–4 раза сильнее любого другого полупрозрачного
   слоя в приложении (модальная подложка и общий оверлей — 4px,
   меню — вообще без блюра). При такой силе размытия элементы под
   панелью при скролле превращаются в цветное пятно — как раз тот
   самый «чрезмерный glassmorphism», который просили убрать. Панель
   заголовка задачи не нуждается в эффекте стекла сильнее, чем
   модальное окно поверх всего интерфейса; снижено на порядок и
   приведено к той же логике, что у остальных полупрозрачных слоёв. */
.panel-top{backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}
/* ==== utilities.204.css ==== */
/* --- Проверено и оставлено без изменений ------------------------
   • Кнопки: .btn-primary/.btn-ghost/.btn-danger/.btn-soft — все до
     единого места использования в разметке сочетаются с базовым
     классом .btn (67+43+35+25+… совпадений), который и задаёт
     высоту, радиус, паддинг, фокус-кольцо и переходы. Ни разу не
     встречен вариант кнопки без .btn — значит, единая визуальная
     логика уже гарантирована для всех четырёх видов (primary как
     основное действие, ghost как второстепенное/«secondary» по
     месту, danger — для необратимых действий, soft — акцентная,
     но тихая) без дополнительных правок.
   • Иерархия действий в подвале модального окна: во всех найденных
     подтверждающих диалогах порядок один и тот же — отмена слева
     нейтральной (ghost) кнопкой, подтверждение/удаление справа
     акцентной или danger-кнопкой. Менять нечего, порядок уже
     единый и предсказуемый.
   • Радиус и тень модального окна, поля формы, чекбоксы и
     радиокнопки (перекрашены в акцент через accent-color) — уже
     приведены к общей системе более ранними разделами этого же
     слоя (7–9, 13); повторно не трогались. */

/* ============================================================
   УЗКИЕ ЭКРАНЫ: ВЕРХНЯЯ ПАНЕЛЬ ДОЛЖНА ПОМЕЩАТЬСЯ ЦЕЛИКОМ

   Блок намеренно стоит В КОНЦЕ таблицы стилей. Первая попытка
   поместить его рядом с остальными правилами для 380px не сработала:
   ниже по файлу идут `@media(max-width:768px){.tb-icon,.tb-burger
   {width:42px;height:42px}}` и `@media (hover:none) and
   (pointer:coarse){.tb-icon{width:42px}}`, а при равной
   специфичности выигрывает правило, объявленное позже. Плюс выше
   задан min-width:40px, который сам по себе не дал бы иконке
   сжаться. Поэтому override и min-width переопределяются здесь.

   Что чинится. При ширине <=768px иконки увеличены до 42x42 ради
   пальца. Внутри .tb-right четыре такие иконки с зазорами требуют
   ~183px, а контейнеру после бургера и кнопки «Создать» достаётся
   ~162px. Дети flex-контейнера не сжимались, а #topbar имеет
   overflow:hidden — поэтому крайняя иконка (переключатель языка и
   соседняя кнопка) просто обрезалась: её не было видно и до неё
   нельзя было дотянуться, горизонтальной прокрутки при этом не
   появлялось, так что проблему легко не заметить.

   Измерено в браузере с эмуляцией касания (pointer:coarse):
   на 375px крайняя иконка заходила за край на 13px, на 320px — на
   26px. 390px и шире помещались всегда.

   36px остаётся приемлемой целью для пальца (общепринятый минимум —
   24px). Правило действует только до 380px включительно, поэтому
   ни рабочий стол, ни планшет не затронуты. */
@media(max-width:380px){
  .tb-icon,.tb-burger{width:36px;height:36px;min-width:36px}
  .tb-right{gap:4px}
}

/* 320px — самый узкий поддерживаемый экран. Здесь 36px уже мало:
   не помещается ещё ~14px. Уменьшаем иконки до 32px (освобождает
   16px на четырёх иконках) — этого достаточно, и 32px по-прежнему
   заметно выше общепринятого минимума в 24px.

   Кнопку «Создать» тронуть нельзя чисто стилями: её подпись —
   это голый текстовый узел, а не элемент, поэтому существующие
   правила `.tb-create span:not(.tb-create-ic){display:none}`
   (в блоках 360px и pointer:coarse) не находят ничего и не
   работают уже сейчас. Чтобы они заработали, подпись пришлось бы
   обернуть в span — но тогда она исчезла бы на ВСЕХ сенсорных
   устройствах, включая планшеты на 768px, а это уже заметное
   изменение оформления, а не исправление узкого экрана. */
@media(max-width:360px){
  .tb-icon,.tb-burger{width:32px;height:32px;min-width:32px}
  .tb-right{gap:3px}
  /* Кнопка «Создать» занимает ~113px — на 320px это и есть основной
     перерасход. Её подпись нельзя скрыть обычным способом: это голый
     текстовый узел, а не элемент, поэтому существующие правила
     `.tb-create span:not(.tb-create-ic){display:none}` (в блоках
     360px и pointer:coarse) не находят ничего и не работают уже
     сейчас. Обернуть подпись в span значило бы поменять разметку и
     убрать её на ВСЕХ сенсорных устройствах, включая планшеты, —
     это уже изменение оформления, а не починка узкого экрана.
     Поэтому гасим текстовый узел через font-size:0 на самой кнопке
     и возвращаем размер иконке внутри. Кнопка остаётся кнопкой,
     доступное имя (aria-label/title) не затрагивается — меняется
     только видимая подпись и только до 360px. */
  .tb-create{font-size:0;padding:0 10px;gap:0}
  .tb-create .tb-create-ic{font-size:var(--t-body)}
}

/* ============================================================
   ВИДИМЫЙ ФОКУС У ПОЛЕЙ БЕЗ РАМКИ
   ============================================================
   В базовом слое есть общее правило
   `:focus-visible{outline:2px solid var(--accent)}` — и его
   достаточно для обычных полей. Но одиннадцать полей
   быстрого ввода (добавление задачи и подзадачи, переименование
   панели и документа, командная строка, поля исполнителя и
   приоритета) объявлены как прозрачные, без рамки, и гасят
   обводку у себя: `outline:none`. Такое правило записано через
   класс, поэтому по весу оно сильнее общего `:focus-visible`
   и побеждает его — то есть при переходе по Tab эти поля не
   получали ВООБЩЕ никакого видимого признака фокуса. Человек,
   работающий с клавиатуры, терял курсор в интерфейсе.

   Возвращаем признак тем же токеном --ring, который уже
   обозначает фокус во всём приложении. Три причины делать это
   здесь, а не в одиннадцати файлах:
     — правило должно загружаться последним, иначе снова проиграет
       по порядку следования;
     — box-shadow не влияет на раскладку, в отличие от outline с
       отступом: ни одно поле не сдвинется;
     — :focus-visible, а не :focus — при щелчке мышью кольцо
       по-прежнему не появляется, привычный вид не меняется.
   ============================================================ */
.add-row input:focus-visible,
.add-sub input:focus-visible,
.add-sub-inline:focus-visible,
.sub-name:focus-visible,
.panel-name:focus-visible,
.doc-title-inp:focus-visible,
.auto-name-input:focus-visible,
.cmdk-input:focus-visible,
.pp-input:focus-visible,
.asg-input:focus-visible,
.guide-area:focus-visible,
.comment-edit-area:focus-visible{box-shadow:var(--ring);border-radius:var(--r-ctl)}
/* ==== features.061.css ==== */
/* ==================================================================
   КОНСТРУКТОР КАБИНЕТА (2.266.0)
   ==================================================================
   Обёртка .dw-item стала ячейкой сетки .dash-wrap вместо самих
   карточек. Поэтому правила ширины, которые раньше применялись к
   карточкам НАПРЯМУЮ, теперь должны применяться к обёртке — иначе
   кабинет поменял бы раскладку, чего задание прямо запрещает.

   Ниже повторена ровно та таблица ширин, которая действует сегодня.
   Она собрана из четырёх существующих файлов, значения не
   придумывались:

     components.019.css   .stat-card         span 3
     components.020.css   .chart-card.half   span 6
                          .chart-card.full   span 12
     utilities.059.css    @max-900           stat span 6, half span 12
     utilities.119.css    @max-768           .dash-wrap 2 колонки,
                                             stat span 1, half/full span 2
     utilities.060.css    @max-640           .dash-wrap одна колонка
     utilities.134.css    @min-1920          half span 3 (четыре в ряд)

   Внутри обёртки собственные ширины карточек больше ничего не
   значат: карточка всегда занимает обёртку целиком (исключение —
   блок kpi, в котором четыре плитки метрик стоят в ряд, как и
   раньше). Поэтому grid-column у детей переопределяется с
   !important: в utilities.060.css у .chart-card стоит
   grid-column:auto!important, и без !important это правило
   перебивало бы наше.

   Пользовательская ширина — переменная --dw-span во встроенном стиле,
   она перекрывает естественную --dw-nat. На планшете и телефоне
   (≤768px) пользовательская ширина ИГНОРИРУЕТСЯ принудительно: там
   колонок две или одна, и блок в шесть колонок вылез бы за экран.
   ================================================================== */

.dw-item{
  display:grid;
  grid-template-columns:1fr;
  gap:inherit;
  min-width:0;
  grid-column:span var(--dw-span,var(--dw-nat,6));
  min-height:var(--dw-h,0);
}

/* Карточка занимает обёртку целиком. min-width:0 обязателен: без него
   содержимое (широкие таблицы, графики) растягивало бы ячейку сетки и
   появлялась бы горизонтальная прокрутка страницы. */
.dw-item>*{grid-column:1/-1!important;min-width:0}

/* Естественные ширины: базовый вид (901–1919px). */
.dw-item.dw-nat-stat{--dw-nat:3}
.dw-item.dw-nat-half{--dw-nat:6}
.dw-item.dw-nat-full{--dw-nat:12}
/* kpi — единственный блок, внутри которого карточек несколько:
   dwKPI() возвращает четыре плитки метрик, и они должны стоять в ряд,
   как сегодня. Служебная панель из этого исключается явно: без
   :not() она заняла бы одну из четырёх ячеек, потому что правило
   с классом dw-nat-kpi перебивает правило .dw-item>* по
   специфичности. */
.dw-item.dw-nat-kpi{--dw-nat:12;grid-template-columns:repeat(4,1fr)}
.dw-item.dw-nat-kpi>*:not(.dw-chrome):not(.dw-resize){grid-column:auto!important}

@media(max-width:900px){
  .dw-item.dw-nat-stat{--dw-nat:6}
  .dw-item.dw-nat-half{--dw-nat:12}
  /* stat-card здесь span 6 из 12 — то есть две плитки в ряд. */
  .dw-item.dw-nat-kpi{grid-template-columns:repeat(2,1fr)}
}

@media(max-width:768px){
  /* Сетка .dash-wrap переходит на две колонки. Пользовательскую
     ширину отключаем: иначе блок вышел бы за пределы экрана. */
  .dw-item{grid-column:span 2!important}
  .dw-item.dw-nat-stat{grid-column:span 1!important}
}

@media(max-width:640px){
  /* Одна колонка. Блоки выстраиваются вертикально, как и требует
     мобильная раскладка. */
  .dw-item{grid-column:1/-1!important}
  .dw-item.dw-nat-kpi{grid-template-columns:repeat(2,1fr)}
}

@media(min-width:1920px){
  .dw-item.dw-nat-half{--dw-nat:3}
}

/* ==================================================================
   ЗАЖАТЬ И ПЕРЕТАЩИТЬ
   ==================================================================
   Работает в обычном режиме, без всякой кнопки. Пока палец держит
   блок, он слегка проседает — это единственная подсказка, что жест
   опознан; ничего не появляется и не сдвигается, поэтому человек,
   который просто нажал и отпустил, изменений не замечает. */

.dw-item.dw-holding{
  transform:scale(.988);
  transition:transform 380ms var(--ease-out);
}

/* Во время перетаскивания выделение текста только мешает: потянув
   мышью, человек выделил бы содержимое вместо переноса блока. */
.dash-wrap.dw-grabbing{user-select:none;-webkit-user-select:none}

/* Взятый блок приподнят. В режиме настройки к этому добавляется
   рамка из правила ниже — в обычном режиме лишних рамок быть не
   должно, поэтому здесь только тень и подъём. */
.dash-wrap .dw-item.dw-dragging{
  /* pointer-events:none обязателен: под пальцем должен опознаваться
     блок ПОД перетаскиваемым, иначе цель вставки не находится. На
     сам жест это не влияет — указатель захвачен (setPointerCapture),
     и события приходят захватившему элементу независимо от
     попадания. */
  pointer-events:none;
  transform:scale(1.012);
  box-shadow:0 12px 28px rgba(0,0,0,.16);
  position:relative;
  z-index:3;
  opacity:.92;
}

@media(prefers-reduced-motion:reduce){
  .dw-item.dw-holding{transform:none;transition:none}
  .dash-wrap .dw-item.dw-dragging{transform:none}
}

/* ==================================================================
   РЕЖИМ НАСТРОЙКИ
   ==================================================================
   В обычном режиме ниже не применяется НИЧЕГО: служебной разметки в
   документе нет вовсе — dwItemOpen() её не выводит. Это не сокрытие
   через display:none, а отсутствие элементов. */

.dw-edit-hint{
  margin:0 var(--gutter) 2px;padding:9px 12px;
  display:flex;align-items:center;gap:8px;
  background:var(--accent-soft);border:1px solid var(--accent-line);
  border-radius:var(--r-md);
  color:var(--accent-700);font-size:var(--t-sm);line-height:1.5;
}

.dw-status{
  font-size:var(--t-xs);color:var(--muted);
  align-self:center;margin-right:2px;white-space:nowrap;
}
.dw-status-error{color:var(--danger)}
.dw-status-saved{color:var(--ok)}

.dash-wrap.dw-editing .dw-item{
  position:relative;
  outline:1px dashed var(--accent-line);
  outline-offset:3px;
  border-radius:var(--r-lg);
}

.dw-item>.dw-chrome{
  grid-column:1/-1!important;
  display:flex;align-items:center;gap:8px;
  padding:0 2px 6px;min-width:0;
}

.dw-name{
  flex:1 1 auto;min-width:0;
  font-size:var(--t-xs);font-weight:600;color:var(--muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}

.dw-btns{display:flex;align-items:center;gap:2px;flex:0 0 auto}

/* 34px — не меньше зоны нажатия, принятой для .auto-icbtn в проекте;
   на телефоне ниже увеличивается до 40. */
.dw-grip,.dw-btn{
  width:34px;height:34px;flex:0 0 auto;
  display:inline-flex;align-items:center;justify-content:center;
  background:transparent;border:1px solid transparent;
  border-radius:var(--r-sm);
  color:var(--muted);cursor:pointer;
  transition:background var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard);
}
.dw-grip:hover,.dw-btn:hover:not(:disabled){background:var(--line-2);color:var(--text)}
.dw-grip:focus-visible,.dw-btn:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.dw-btn:disabled{opacity:.35;cursor:default}

/* touch-action:none только на рукоятке. На всей остальной площади
   блока касание работает как раньше — страница прокручивается,
   кнопки и поля внутри блока нажимаются. */
.dw-grip{cursor:grab;touch-action:none}
.dw-grip:active{cursor:grabbing}

.dw-sign{font-size:15px;font-weight:700;line-height:1}

/* z-index обязателен. Уголок и карточка оба позиционированы
   (карточка — position:relative) и без z-index рисуются в порядке
   DOM. Уголок в разметке стоит раньше карточки, поэтому карточка
   ложилась поверх и забирала нажатие: до 2.269.1 уголок не работал и
   даже не был виден. */
.dw-resize{
  position:absolute;right:2px;bottom:2px;z-index:3;
  width:26px;height:26px;
  cursor:nwse-resize;touch-action:none;
  border-right:2px solid var(--accent);
  border-bottom:2px solid var(--accent);
  border-bottom-right-radius:var(--r-sm);
  opacity:.5;
}
.dw-resize:hover{opacity:1}

/* В режиме настройки взятый блок дополнительно обводится: там уже
   есть рамки у всех блоков, и без обводки взятый терялся бы среди
   них. Подъём и тень приходят из общего правила выше. */
.dash-wrap.dw-editing .dw-item.dw-dragging{
  outline:2px dashed var(--accent);
  outline-offset:3px;
}

.dw-item.dw-resizing{outline:2px solid var(--accent);outline-offset:3px}

@media(max-width:640px){
  .dw-grip,.dw-btn{width:40px;height:40px}
  .dw-resize{width:34px;height:34px}
  .dw-edit-hint{margin:0 var(--gutter) 2px}
  .dw-name{font-size:var(--t-micro)}
}

@media(prefers-reduced-motion:reduce){
  .dw-grip,.dw-btn{transition:none}
}
/* ==== features.062.css ==== */
/* ==================================================================
   «ГЛАВНАЯ»: ШИРИНА БЛОКОВ (2.268.0)
   ==================================================================
   «Главная» — одна колонка шириной 720 px по центру
   (utilities.028.css). Блок, которому человек задал ширину, может
   стать и уже, и ШИРЕ этой колонки — симметрично в обе стороны,
   оставаясь по центру.

   Как это сделано без transform. Отрицательные поля слева и справа,
   равные половине разницы между шириной блока и шириной колонки:
   при блоке шире колонки поля уходят в минус, и блок выступает на
   одинаковое расстояние с обеих сторон. transform здесь не
   годится: он создаёт новый блок содержания для position:fixed, и
   выпадающие меню внутри виджета поехали бы.

   Защита от обрезки. У #main стоит overflow-x:clip: блок шире
   доступного места браузер не прокручивает, а молча отрезает.
   Поэтому ширина берётся как min(желаемая, доступная), где доступную
   (--hw-avail) пишет скрипт по факту, а 1120px — страховка на случай,
   если скрипт её не выставил.

   Без заданной ширины (--hw-w не выставлена) правило ниже не
   срабатывает вовсе: блок выглядит ровно как раньше.
   ================================================================== */

.hw-block{position:relative}

.hw-block[style*="--hw-w"]{
  --hw-eff:min(var(--hw-w),var(--hw-avail,1120px));
  width:var(--hw-eff);
  max-width:none;
  margin-left:calc((100% - var(--hw-eff)) / 2);
  margin-right:calc((100% - var(--hw-eff)) / 2);
}

/* Края. В покое их не видно вовсе — ни полосы, ни значка: страница
   выглядит как раньше. Под курсором край подсвечивается тонкой
   линией, а сам курсор становится «↔». Ширина зоны захвата 14 px —
   достаточно, чтобы попасть мышью, и не перекрывает содержимое
   блока (у .widget внутренний отступ 22 px). */
.hw-edge{
  position:absolute;top:10px;bottom:10px;
  width:14px;z-index:2;
  cursor:ew-resize;
  /* Только на краях: на остальной площади блока касание работает
     как раньше — прокручивает страницу и нажимает элементы. */
  touch-action:none;
  border-radius:var(--r-sm);
}
.hw-edge-l{left:-7px}
.hw-edge-r{right:-7px}

.hw-edge::after{
  content:"";position:absolute;top:0;bottom:0;left:50%;
  width:3px;margin-left:-1.5px;border-radius:2px;
  background:var(--accent);
  opacity:0;
  transition:opacity var(--dur-fast) var(--ease-standard);
}
.hw-edge:hover::after,
.hw-block.hw-resizing .hw-edge::after{opacity:.55}
.hw-edge:focus-visible{outline:none}
.hw-edge:focus-visible::after{opacity:1}

/* Во время растягивания выделение текста только мешает. */
.home-wrap.hw-busy{user-select:none;-webkit-user-select:none;cursor:ew-resize}

/* ------------------------------------------------------------------
   Узкие экраны
   ------------------------------------------------------------------
   На телефоне и узком планшете блоки всегда во всю ширину, как
   сегодня: растягивать там некуда, а выступающий блок дал бы
   обрезку. Края убраны совсем — и из-под пальца, и из порядка Tab. */
@media(max-width:768px){
  .hw-block[style*="--hw-w"]{width:auto;margin-left:0;margin-right:0}
  .hw-edge{display:none}
}

@media(prefers-reduced-motion:reduce){
  .hw-edge::after{transition:none}
}

@media print{
  .hw-edge{display:none}
  .hw-block[style*="--hw-w"]{width:auto;margin-left:0;margin-right:0}
}
/* ==== features.063.css ==== */
/* ==================================================================
   СТРОКИ ЗАДАЧ: НЕ СЧИТАТЬ ТО, ЧЕГО НЕ ВИДНО (2.272.0)
   ==================================================================
   Замер (tools/browser/probe-render-perf.mjs, процессор ×4 — как у
   среднего телефона): перерисовка списка проекта при 1 000 задач —
   721 мс, «Моих задач» при 3 000 — 936 мс. Синхронизация перерисовывает
   экран при каждом изменении коллег, то есть это регулярное подвисание.
   Профиль (probe-render-profile.mjs): построение HTML — 1–3% времени,
   пересчёт стилей и раскладка — около 73%. Дорого не посчитать задачи,
   а разложить на экране строки, которых всё равно не видно.

   content-visibility:auto — браузер не считает стили, раскладку и
   отрисовку строки, пока она за пределами экрана. Видимые строки
   рисуются как раньше. Тот же приём проект уже применял к карточкам
   доски (.card), строкам хронологии (.tl2-row) и списку проектов
   (.proj-item) — строкам задач его не хватало.

   44px — измеренная высота строки. auto: браузер запоминает настоящую
   высоту строки, однажды её отрисовав, — полоса прокрутки не прыгает.

   Для печати оптимизация уже отключена в utilities.070.css — .task-row
   там перечислен. */
.task-row{content-visibility:auto;contain-intrinsic-size:auto 0px auto 44px}
/* ==== features.064.css ==== */
/* ==================================================================
   ВЁРСТКА ПОСЛЕ ПРОВЕРКИ НА ТРЁХ ЯЗЫКАХ И ДВУХ ШИРИНАХ (2.280.0)
   ==================================================================
   tools/browser/probe-overflow.mjs — обрезанный, вылезающий и
   выходящий за экран текст на каждом экране × языке × ширине. */

/* 1. Список задач: шапка и строки — одинаковая ширина содержимого.
   Раньше у шапки слева 40px, у строк 12px: пока колонки были
   фиксированными, разницу молча съедал 1fr. С 2.280.0 колонки
   сжимаемые (listColsString: minmax), и при разной ширине содержимого
   шапка и строки сжимались бы по-разному — заголовки уехали бы с
   данных. Сдвиг надписи «Задача» (чтобы она стояла над текстом
   названия, а не над галочкой) переезжает внутрь её ячейки: визуально
   надпись на том же месте, 12 + 28 = 40. */
.list-colhead{padding-left:12px}
.list-colhead>.ch:first-child{padding-left:28px}

/* 2. «Сегодня» в календаре унаследовало размер квадратных стрелок
   ‹ › — ровно 32px, а само слово шире (41px по-русски). */
.cal-nav [data-act="cal-today"]{width:auto;min-width:32px;padding:0 10px;white-space:nowrap}

/* 3. Кнопки в шапке страницы «Люди» уходили за край телефона (три кнопки
   в ряд, 459px на экране 390px). Правило здесь НЕ нужно: в проекте уже
   есть стандартный класс шапки .ph-actions с переносом на экранах до
   640px (utilities.060.css). Страница «Люди» писала свой ряд встроенным
   стилем в обход него — теперь пользуется стандартным классом
   (features/workspace/service.js). */

/* 4. Список задач на экранах 769–900 px (планшет портретно).
   utilities.059.css задаёт здесь три колонки (1fr 120px 90px) и прячет
   4-ю и 5-ю ячейки. Правило писалось, когда ячеек было пять; теперь в
   строке ещё колонка меню и свои поля проекта — они не прятались и
   переезжали на вторую строку сетки (высота строки 67px вместо 44).
   Видны название, исполнитель, срок и меню; всё остальное скрыто.
   !important — у подзадач ширина задана встроенным стилем.
   До 768px строки — карточки (display:flex, utilities.135.css), их это
   правило не касается. */
@media (min-width:769px) and (max-width:900px){
  .list-colhead,.task-row{grid-template-columns:minmax(0,1fr) 120px 90px 28px!important}
  .list-colhead>*:nth-child(n+4):not(:last-child),.task-row>*:nth-child(n+4):not(:last-child){display:none!important}
}
/* ==== features.065.css ==== */
/* 2.289.0 — шапка панели задачи по образцу Asana, лайки,
   полоса «задача завершена», празднование завершения. */

.panel-tools{display:flex;align-items:center;gap:2px}
.panel-tool{position:relative;height:32px;min-width:32px;padding:0 7px;border-radius:var(--r-sm);display:inline-flex;align-items:center;justify-content:center;gap:4px;color:var(--muted);transition:background var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard),transform var(--dur-fast) var(--ease-snap)}
.panel-tool:hover{background:var(--surface-3);color:var(--ink)}
.panel-tool:active{transform:scale(.92)}
.panel-tool:focus-visible{outline:2px solid var(--accent-ring);outline-offset:1px}
.panel-like.on{color:var(--accent-700)}
.panel-like.on svg{animation:likePop var(--dur-slow) var(--ease-spring)}
.panel-like-n{font-size:var(--t-sm);font-weight:600;line-height:1}
.panel-top-sep{width:1px;height:20px;background:var(--line-2);margin:0 4px}
.panel-top .panel-complete{margin-right:0}

@keyframes likePop{0%{transform:scale(1)}40%{transform:scale(1.3) rotate(-12deg)}100%{transform:scale(1)}}

.panel-done-banner{display:flex;align-items:center;gap:8px;padding:9px 18px;background:var(--ok-soft);border-bottom:1px solid var(--ok-line);color:var(--ok-strong);font-size:var(--t-sm);font-weight:600;flex-shrink:0}
.panel-done-banner svg{flex-shrink:0}

.like-badge.on{color:var(--accent-700)}

/* Узкий экран: иконки «ссылка» и «во весь экран» — в меню «…» они тоже есть. */
@media (max-width:520px){
  .panel-tools [data-act="panel-copy-link"],.panel-tools [data-act="open-focus"]{display:none}
  .panel-top-sep{display:none}
}

/* Празднование: зверёк пролетает слева направо по дуге. */
.celebrate{position:fixed;left:0;width:100vw;height:0;pointer-events:none;z-index:9999;overflow:visible}
.celebrate-creature{position:absolute;left:-12vw;top:0;font-size:64px;line-height:1;will-change:transform;animation:celebrateFly 2.6s var(--ease-standard) forwards;filter:drop-shadow(0 6px 10px rgba(0,0,0,.18))}
.celebrate-big .celebrate-creature{font-size:96px;animation-duration:3s}
@keyframes celebrateFly{
  0%{transform:translate(0,40px) rotate(-8deg);opacity:0}
  10%{opacity:1}
  50%{transform:translate(62vw,-60px) rotate(6deg)}
  90%{opacity:1}
  100%{transform:translate(124vw,20px) rotate(-4deg);opacity:0}
}
@media (prefers-reduced-motion:reduce){
  .celebrate{display:none}
  .panel-like.on svg{animation:none}
}
/* ==== features.066.css ==== */
/* 2.290.0 — «Мои задачи» по разделам. */
.my-group-toggle{display:inline-flex;align-items:center;gap:2px;padding:2px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface)}
.my-group-btn{padding:5px 10px;border-radius:calc(var(--r-sm) - 2px);font-size:var(--t-sm);font-weight:600;color:var(--muted);transition:background var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard)}
.my-group-btn:hover{color:var(--ink)}
.my-group-btn.on{background:var(--accent-soft);color:var(--accent-700)}
.my-group-btn:focus-visible,.my-opts:focus-visible{outline:2px solid var(--accent-ring);outline-offset:1px}
.my-opts{width:30px;height:30px}

.my-sec-head .my-sec-menu{margin-left:auto;opacity:0;transition:opacity var(--dur-fast) var(--ease-standard)}
.my-sec-head:hover .my-sec-menu,.my-sec-menu:focus-visible{opacity:1}
.my-sec-empty{padding:10px 12px 10px 40px;font-size:var(--t-sm);color:var(--faint);border:1px dashed var(--line-2);border-radius:var(--r-sm);margin:4px 0}
.bc-body .my-sec-empty{padding:14px 10px;text-align:center;margin:0}
.task-rows.dnd-over .my-sec-empty,.drag-over .my-sec-empty{border-color:var(--accent-line);color:var(--accent-700)}
.my-rows{min-height:8px}

.my-sec-add{display:inline-flex;align-items:center;gap:6px;margin:10px 0 4px 12px;padding:7px 12px;border-radius:var(--r-sm);font-weight:600;font-size:var(--t-sm);color:var(--muted)}
.my-sec-add:hover{background:var(--surface-3);color:var(--ink)}
.my-col-add{background:transparent;border:1px dashed var(--line-2);box-shadow:none;align-items:flex-start;justify-content:flex-start}
.my-col-add .my-sec-add{margin:8px}

.my-move-btn{opacity:0}
.task-row:hover .my-move-btn,.my-move-btn:focus-visible{opacity:1}
@media (hover:none){.my-move-btn,.my-sec-head .my-sec-menu{opacity:1}}

.my-sec-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;margin-right:8px}
.menu-note{padding:4px 12px 8px 38px;font-size:var(--t-xs);line-height:1.45;color:var(--muted);max-width:300px;white-space:normal}
.task-row[draggable="true"]{cursor:grab}
.task-row[draggable="true"]:active{cursor:grabbing}
/* ==== features.067.css ==== */
/* 2.291.0 — подзадачи как полноценные задачи. */
.sub-crumb{display:flex;align-items:center;flex-wrap:wrap;gap:4px;margin:0 0 6px;color:var(--muted);font-size:var(--t-sm)}
.sub-crumb svg{flex-shrink:0;margin-right:2px}
.sub-crumb-link{max-width:260px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:2px 6px;border-radius:var(--r-xs);color:var(--ink-2);font-weight:600}
.sub-crumb-link:hover{background:var(--surface-3);color:var(--accent-700)}
.sub-crumb-link:focus-visible{outline:2px solid var(--accent-ring);outline-offset:1px}
.sub-crumb-sep{color:var(--faint)}
.subtask .sub-open{opacity:.55}
.subtask:hover .sub-open,.sub-open:focus-visible{opacity:1;color:var(--accent-700)}
.subtask .sub-kids{margin-left:2px}
.mini-parent{display:inline-flex;align-items:center;gap:4px;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background:var(--surface-3);color:var(--ink-2);cursor:pointer}
.mini-parent:hover{color:var(--accent-700)}
/* ==== features.068.css ==== */
/* 2.292.0 — новые типы полей. */
.cf-num{font-variant-numeric:tabular-nums}
.cf-formula{color:var(--accent-700)}
.cf-id{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:var(--t-sm);font-weight:600;color:var(--ink-2)}
.cf-check-btn{display:inline-flex;align-items:center;justify-content:center;min-width:22px;height:22px;padding:0;border-radius:var(--r-xs);background:transparent}
.cf-check-btn.field-btn{justify-content:flex-start}
.cf-check{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:5px;border:1.5px solid var(--line-3);color:transparent;transition:background var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard)}
.cf-check.on{background:var(--ok);border-color:var(--ok);color:#fff}
.cf-check-btn:hover .cf-check:not(.on){border-color:var(--accent-line)}
.cf-check-btn:focus-visible{outline:2px solid var(--accent-ring);outline-offset:1px}
.cf-ro{cursor:default;color:var(--faint)}
.field-btn.cf-ro{cursor:help}
.cf-ro-note code,.form-hint code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.92em;background:var(--surface-3);padding:1px 5px;border-radius:4px}
.cf-formula-src{display:block;margin-top:6px;white-space:pre-wrap;word-break:break-word}
.cf-fmt-row{display:grid;grid-template-columns:2fr 1fr 1fr;gap:8px}
.form-hint{margin-top:6px;font-size:var(--t-xs);line-height:1.5;color:var(--muted)}
.form-hint code{margin:0 2px;display:inline-block}
.cf-extra[hidden]{display:none}
/* ==== features.069.css ==== */
/* 2.293.0 — свои шаблоны проектов. */
.link-btn{display:inline-block;margin-top:6px;padding:0;background:none;border:0;color:var(--accent-700);font-size:var(--t-sm);font-weight:600;cursor:pointer}
.link-btn:hover{text-decoration:underline}
.link-btn:focus-visible{outline:2px solid var(--accent-ring);outline-offset:2px;border-radius:3px}
.pt-row{align-items:center}
.pt-emoji{font-size:18px;width:26px;flex-shrink:0;text-align:center}
.pt-row .fld-name{display:flex;flex-direction:column;min-width:0}
.pt-desc{font-size:var(--t-xs);color:var(--muted);font-weight:400;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pt-empty{padding:12px 2px;font-size:var(--t-sm);color:var(--muted);line-height:1.5}
#npStartRow[hidden]{display:none}
/* ==== features.070.css ==== */
/* 2.294.0 — справка по Tab-сочетаниям. */
.sc-note{margin-top:10px;padding:8px 10px;border-radius:var(--r-sm);background:var(--surface-2,var(--surface-3));font-size:var(--t-xs);line-height:1.5;color:var(--muted)}
/* ==== features.071.css ==== */
/* 2.295.0 — доска: столбцы по полю и настройка карточек. */
.board-tools{display:flex;gap:6px;flex-wrap:wrap;margin:0 0 10px}
.board-tool b{font-weight:700;margin-left:2px}
.board-tool svg:last-child{margin-left:2px;opacity:.7}
.board-col-g .bc-head{cursor:default}
.bc-av{line-height:0;flex-shrink:0}
.menu-cb{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:4px;border:1.5px solid var(--line-3);margin-right:8px;flex-shrink:0;color:#fff}
.menu-cb.on{background:var(--accent);border-color:var(--accent)}
.card-cf{display:inline-flex;align-items:center;gap:4px;max-width:100%;font-size:11px;padding:1px 6px;border-radius:var(--r-xs);background:var(--surface-3);color:var(--ink-2);overflow:hidden}
.card-cf-l{color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:90px}
.card-cf .cf-val,.card-cf .status-tag{font-size:11px}
.card-cf .cf-check{width:14px;height:14px}
/* ==== features.072.css ==== */
/* 2.297.0 — список: группы по полю и итоги. */
.lg-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0;margin-right:2px}
.lg-av{line-height:0;flex-shrink:0;margin-right:2px}
.sum-row{background:transparent;border-top:1px dashed var(--line-2);cursor:default;min-height:34px;font-variant-numeric:tabular-nums}
.sum-row:hover{background:transparent}
.sum-label{font-size:var(--t-xs);font-weight:700;letter-spacing:.02em;text-transform:uppercase;color:var(--muted)}
.sum-cell{font-size:var(--t-sm);font-weight:700;color:var(--ink-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sum-empty{color:var(--faint);font-weight:400}
.sum-k{font-weight:600;color:var(--muted);margin-right:4px}
/* ==== features.073.css ==== */
/* 2.298.0 — «Сделать подзадачей». */
/* Цель — поверх правого края ячейки названия, а не в потоке: в узкой
   колонке (много полей) элемент в потоке вылезал под соседнюю ячейку
   «Исполнитель» и был недоступен для броска — найдено проверкой в
   браузере (tools/browser/check-asana.mjs). */
.task-row .task-main{position:relative}
.row-nest-drop{display:none;position:absolute;right:4px;top:50%;margin-top:-12px;z-index:3;align-items:center;justify-content:center;width:30px;height:24px;border-radius:var(--r-sm);border:1.5px dashed var(--accent-line);color:var(--accent-700);background:var(--accent-soft)}
body.dnd-active .task-row:not(.dragging) .row-nest-drop{display:inline-flex}
.row-nest-drop.on{background:var(--accent);border-style:solid;border-color:var(--accent);color:#fff;transform:scale(1.08)}
.row-nest-drop svg{pointer-events:none}
.nest-search-wrap{padding:6px 10px 4px}
.nest-search-wrap .field-input{width:260px;max-width:100%}
.nest-list{max-height:300px;overflow:auto}
.nest-item{display:flex;flex-direction:column;align-items:flex-start;gap:1px;line-height:1.3}
.nest-title{font-weight:600;max-width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.nest-where{font-size:var(--t-xs);color:var(--muted);max-width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.nest-done .nest-title{color:var(--muted);text-decoration:line-through}
/* ==== features.074.css ==== */
/* 2.304.0 — контраст тёмной темы (axe-core, WCAG 2.1 AA, 4,5:1).
   Все значения посчитаны по формуле WCAG, «было → стало»:

   • Основные кнопки: в 2.288.0 акцент тёмной темы сменили на #705FF3,
     подобрав его под БЕЛЫЙ текст (4,55:1), но цвет текста на акценте
     (--accent-fg) остался тёмным #0B0C12 из utilities.001.css — 4,30:1.
     Теперь белый: 4,55:1.
   • «+ зависимость», «+ файл» в панели — акцент текстом на тёмной
     поверхности #262933: 3,19:1 → --accent-600 #9C90FF: 5,42:1.
   • Выбранный пункт меню на подсветке #343549: #9C90FF 4,48:1 →
     --accent-700 #B0A6FF: 5,56:1.
   • Просроченный срок и «Заблокировано» на красной подложке #443239:
     #FF6B5E 4,27:1 → #FF8A80: 5,22:1.
   • Аватары средних цветов — чёрный текст вместо почти чёрного
     (core/format.js, avFg): синий #2A7DE0 4,39:1 → 5,11:1. */
[data-theme="dark"]{--accent-fg:#FFFFFF}
[data-theme="dark"] .add-dep-btn{color:var(--accent-600)}
[data-theme="dark"] .menu-item.sel{color:var(--accent-700)}
[data-theme="dark"] .due-pill.over,[data-theme="dark"] .blocked-badge{color:#FF8A80}

/* Завершённые строки и карточки были полупрозрачными (opacity .72): вся
   их начинка — вехи, приоритет, просроченный срок, название — падала
   до 3,7–4,3:1. Признаков завершения и так три: зелёная отметка,
   зачёркнутое название и его приглушённый цвет (--faint подобран не
   ниже 4,5:1). Прозрачность убрана, как в Asana — завершённое серое, но
   читаемое. */
.task-row.done,.card.done{opacity:1}

/* Полоса «задача завершена» (2.289.0) в светлой теме: зелёный #16A06A на
   светло-зелёной подложке #EAF7F1 — 3,04:1 → #0F7A50: 4,87:1. В тёмной
   теме --ok-strong и так проходит. */
:root:not([data-theme="dark"]) .panel-done-banner{color:#0F7A50}
/* ==== features.075.css ==== */
/* Уровни доступа к проекту (2.305.0): значок в шапке проекта, режим
   «только чтение» для наблюдателя и комментатора, окно «Роли в проекте».
   Скрытие кнопок — только подсказка интерфейса: правку, на которую нет
   прав, откатывает guardRoleEdits() и отвергает сервер. */

.ro-badge{display:inline-flex;align-items:center;height:26px;padding:0 10px;margin-right:8px;border-radius:999px;
  background:var(--warn-soft);color:var(--warn);border:1px solid var(--warn-line);font-size:var(--t-xs);font-weight:600;white-space:nowrap}

/* Страница проекта: нечего показывать кнопки, которые ничего не сделают. */
.page.ro-viewer [data-act="add-task-quick"],.page.ro-commenter [data-act="add-task-quick"],
.page.ro-viewer [data-act="add-task-inline"],.page.ro-commenter [data-act="add-task-inline"],
.page.ro-viewer [data-act="add-task-menu"],.page.ro-commenter [data-act="add-task-menu"],
.page.ro-viewer [data-act="add-section"],.page.ro-commenter [data-act="add-section"],
.page.ro-viewer [data-act="new-task"],.page.ro-commenter [data-act="new-task"],
.page.ro-viewer .add-row,.page.ro-commenter .add-row,
.page.ro-viewer .add-task-input,.page.ro-commenter .add-task-input,
.page.ro-viewer .pm-composer{display:none!important}

/* Панель задачи. */
.ro-note{margin:10px 16px 0;padding:8px 12px;border-radius:8px;background:var(--warn-soft);color:var(--warn);
  border:1px solid var(--warn-line);font-size:var(--t-xs);line-height:1.45}
#panel.ro-viewer .comment-box{display:none}
#panel.ro-viewer .field-val,#panel.ro-commenter .field-val,
#panel.ro-viewer .sub-check,#panel.ro-commenter .sub-check,
#panel.ro-viewer .sub-drag,#panel.ro-commenter .sub-drag,
#panel.ro-viewer [data-act="add-sub"],#panel.ro-commenter [data-act="add-sub"],
#panel.ro-viewer [data-act="add-dep"],#panel.ro-commenter [data-act="add-dep"],
#panel.ro-viewer [data-act="add-attach"],#panel.ro-commenter [data-act="add-attach"]{pointer-events:none}
#panel.ro-viewer [data-act="add-sub"],#panel.ro-commenter [data-act="add-sub"],
#panel.ro-viewer [data-act="add-dep"],#panel.ro-commenter [data-act="add-dep"],
#panel.ro-viewer [data-act="add-attach"],#panel.ro-commenter [data-act="add-attach"]{display:none}

/* Окно «Роли в проекте». */
.proj-role-hint{margin-top:6px;font-size:var(--t-xs);color:var(--muted);line-height:1.45}
.proj-role-legend{margin-top:12px;font-size:var(--t-xs);color:var(--muted)}
.proj-role-legend summary{cursor:pointer;color:var(--ink-2);font-weight:600;margin-bottom:6px}
.proj-role-legend-row{padding:3px 0;line-height:1.45}
.proj-role-legend-row b{color:var(--ink-2)}
.proj-role-row .auto-select[disabled]{opacity:1;cursor:not-allowed;color:var(--muted)}
/* ==== features.076.css ==== */
/* Окно «Сроки и зависимости» (2.306.0): рабочие дни и режим автосдвига. */
.sch-set{border:0;margin:0 0 14px;padding:0;min-width:0}
.sch-days{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}
.sch-day{display:inline-flex;align-items:center;gap:6px;min-height:36px;padding:0 12px;border:1px solid var(--line);border-radius:8px;cursor:pointer;font-size:var(--t-sm);color:var(--ink-2)}
.sch-day:has(input:checked){border-color:var(--accent);background:var(--accent-soft);color:var(--ink)}
.sch-day:has(input:focus-visible){outline:2px solid var(--accent);outline-offset:2px}
.sch-day:has(input:disabled),.sch-mode:has(input:disabled){cursor:not-allowed}
.sch-mode{display:flex;gap:10px;align-items:flex-start;padding:10px 12px;margin-top:6px;border:1px solid var(--line);border-radius:10px;cursor:pointer;line-height:1.4}
.sch-mode:has(input:checked){border-color:var(--accent);background:var(--accent-soft)}
.sch-mode input{margin-top:3px;flex:none}
.sch-mode b{display:block;color:var(--ink);font-size:var(--t-sm)}
.sch-desc{display:block;color:var(--muted);font-size:var(--t-xs);margin-top:2px}

/* 2.315.0: на телефоне день и режим — цель не ниже 44px */
@media (hover: none) and (pointer: coarse) {
  .sch-day { min-height: 44px; }
  .sch-mode { padding: 12px; }
}
/* ==== features.077.css ==== */
/* «Входящие» (2.307.0): закладка, «напомнить позже», архив. Как кнопка
   «прочитано» — по наведению и фокусу, на сенсорных экранах — всегда.
   Закладку видно всегда, если она поставлена: это состояние, а не действие. */
.inbox-acts{position:absolute;right:12px;top:50%;transform:translateY(-50%);display:flex;gap:2px;padding:2px;
  border-radius:var(--r-sm);background:var(--surface);opacity:0;transition:opacity var(--dur-instant)}
.inbox-read ~ .inbox-acts{right:44px}
.inbox-item:hover .inbox-acts,.inbox-item:focus-within .inbox-acts{opacity:1}
.inbox-act{width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:var(--r-xs);color:var(--muted)}
.inbox-act:hover{background:var(--well);color:var(--ink)}
.inbox-act:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.inbox-act.on{color:var(--warn)}
.inbox-act.on svg{fill:currentColor}
.inbox-item:not(:hover):not(:focus-within) .inbox-acts:has(.inbox-act.on){opacity:1;background:transparent}
.inbox-item:not(:hover):not(:focus-within) .inbox-acts:has(.inbox-act.on) .inbox-act:not(.on){visibility:hidden}
.inbox-snz{position:absolute;right:16px;bottom:6px;font-size:var(--t-xs);color:var(--muted)}
@media(hover:none){.inbox-acts{opacity:1}}
/* ==== features.078.css ==== */
/* Базовый план на хронологии (2.308.0): полоса плана под полосой задачи
   и отставание рядом. Полоса плана — штриховка, а не цвет: план нужно
   отличать от задачи и без различения цветов. */
.tl2-row.has-base .tl2-bar{top:calc(50% - 3px)}
.tl2-row.has-base .tl2-ms{margin-top:-3px}
.tl2-base{position:absolute;bottom:2px;height:5px;border-radius:2px;pointer-events:none;
  background:repeating-linear-gradient(135deg,var(--muted) 0 2px,transparent 2px 4px);border:1px solid var(--muted);box-sizing:border-box;opacity:.75}
.tl2-base.ms{height:6px}
.tl2-slip{position:absolute;top:50%;transform:translateY(-50%);font-size:var(--t-xs);font-weight:600;white-space:nowrap;pointer-events:none;
  padding:1px 6px;border-radius:999px;line-height:1.5}
.tl2-slip.late{color:var(--danger);background:var(--danger-soft)}
.tl2-slip.early{color:var(--ok);background:var(--ok-soft)}
.tl2-slip.new{color:var(--muted);background:var(--well);font-weight:500}
/* ==== features.079.css ==== */
/* Окно «Пакет» (2.309.0). */
.bdl-card{padding:12px 14px;border:1px solid var(--line);border-radius:10px;margin-bottom:10px}
.bdl-name{display:flex;align-items:center;gap:8px;font-weight:600;color:var(--ink)}
.bdl-v{font-weight:500;font-size:var(--t-xs);color:var(--muted)}
.bdl-meta{margin-top:4px;font-size:var(--t-xs);color:var(--muted);line-height:1.45}
.bdl-note{margin-bottom:10px}
.bdl-actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}
.bdl-row{display:flex;gap:8px;align-items:center}
.bdl-row .form-input,.bdl-row .auto-select{flex:1;min-width:0}
/* ==== features.080.css ==== */
/* Учёт времени (2.320.0): идущий таймер.
   На компьютере — в левом меню: его не закрывает панель задачи и не
   перекрывает поиск, стоящий по центру шапки поверх соседей. На телефоне
   меню спрятано, а поиска в шапке нет — там таймер в шапке. */
.tm-chip{display:flex;align-items:center;gap:6px;padding:4px 4px 4px 10px;border-radius:999px;background:var(--accent-soft,rgba(91,80,240,.12));font-size:13px;min-width:0;max-width:100%}
.tm-chip .tm-el{font-variant-numeric:tabular-nums;font-weight:600;flex-shrink:0}
.tm-chip .tm-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;flex:1}
.tm-chip .tm-stop{flex-shrink:0;width:26px;height:26px}
.tm-slot-side{margin:6px 10px 2px;container-type:inline-size}
.tm-slot-side:empty{display:none}
.tm-slot-top{display:none}
@container (max-width:140px){.tm-slot-side .tm-title{display:none}}
@media(max-width:768px){.tm-slot-side{display:none}.tm-slot-top{display:contents}.tm-slot-top .tm-chip{max-width:46vw}}
/* ==== theme.999.palette.css ==== */
/* ==================================================================
   ПАТЧ ПАЛИТРЫ: РАЗДЕЛЕНИЕ СЛОЁВ ПОВЕРХНОСТЕЙ
   ==================================================================
   Подключается ПОСЛЕДНИМ и переопределяет только цвета поверхностей
   и два токена вторичного текста. Больше ничего не трогает.
   ОТКАТ: убрать одну строку @import в index.css — вернётся прежний
   вид, остальной код от этого файла не зависит.

   ЧТО ИСПРАВЛЯЕТСЯ

   Замер контраста между соседними слоями показал, что иерархия
   поверхностей схлопнута — отсюда ощущение одной серой плоскости:

     --chrome-2 / --canvas   #ECECF0 → #ECECF0   1.000
     --surface  / --raised   #F0F0F3 → #F0F0F3   1.000
     --canvas   / --surface  #ECECF0 → #F0F0F3   1.036
     --chrome   / --chrome-2 #E8E8EB → #ECECF0   1.038

   Две пары совпадали до символа: боковая панель заливалась тем же
   цветом, что рабочая область, а модальное окно — тем же, что
   карточка под ним. Остальные различались примерно на полтора
   процента светлоты, то есть ниже порога различимости для крупных
   плоскостей. В тёмной теме то же самое: три пары ниже 1.05.

   Отдельно --faint (даты, счётчики, метаданные) давал в светлой
   теме 2.77:1 — ниже порога WCAG AA даже для крупного текста. В
   тёмной теме тот же токен давал 4.86, то есть просела именно
   светлая.

   КАК ПОСЧИТАНО

   Значения не подобраны на глаз. Задана лестница относительной
   яркости с постоянным шагом (1.085 в светлой теме, 1.10 в тёмной)
   и переведена обратно в цвет с сохранением исходного синеватого
   оттенка палитры — менялась только светлота. Порог 1.08 взят как
   граница, ниже которой разница двух больших плоскостей перестаёт
   читаться.

   Светлая лестница привязана к белому сверху, поэтому рабочая
   область --canvas осталась ровно прежней (#ECECF0) — менялось
   только то, что лежит над ней и под ней. Это сознательно
   консервативный выбор: основной фон, на который человек смотрит
   весь день, не сдвинут ни на тон.

   ПРОВЕРЕНО РАСЧЁТОМ, НЕ ГЛАЗАМИ. Все 14 соседних пар дают ≥1.08,
   весь текст проходит WCAG (--faint поднялся с 2.77 до 3.61).
   Как это выглядит в браузере — нужно смотреть.
   ================================================================== */

:root{
  --raised:#FFFFFF;
  --surface:#F5F5F7;
  --canvas:#ECECF0;
  --chrome-2:#E3E3E9;
  --chrome:#DBDBDF;
  --well:#E3E3E9;
  --surface-2:#E1E1E8;
  --surface-3:#E3E3E8;
  /* Серые для текста (2.288.0): faint — не ниже 4,5:1 на самом тёмном
     элементе интерфейса (#DBDBDF), muted — не ниже 6:1. Было: faint
     #767A8C — 3,08:1 (ниже WCAG AA). */
  --muted:#4A4D5C;
  --faint:#5D606F;
}

/* Акцент в тёмной теме (2.288.0): #8B7DF5 давал белому тексту кнопки
   3,3:1 при норме 4,5:1 (axe-core, WCAG 2.1 AA). #705FF3 — 4,55:1. */
[data-theme="dark"]{
  --accent:#705FF3;
  --chrome:#0C0D11;
  --chrome-2:#17181F;
  --canvas:#1F212A;
  --surface:#262933;
  --raised:#2C2F3A;
  --well:#171820;
  --surface-2:#30333F;
  --surface-3:#333642;
  /* Серые для текста тёмной темы (2.288.0). Раньше их здесь НЕ БЫЛО, и
     тёмная тема получала серые СВЕТЛОЙ темы из :root выше: у :root и
     [data-theme="dark"] одинаковая специфичность, а этот файл в каскаде
     последний и перекрывал тёмные значения из utilities.001.css.
     Второстепенный текст на тёмном фоне давал 1,93:1 и 2,82:1 при
     норме 4,5:1 (аудит axe-core, WCAG 2.1 AA), а иерархия была
     перевёрнута: muted темнее faint. Здесь: faint — не ниже 4,5:1 на
     самой светлой карточке (#333642), muted — не ниже 6:1. */
  --muted:#B3B7C5;
  --faint:#9A9EAD;
}
/* ==== theme.999.refresh.css ==== */
/* ==================================================================
   ОБНОВЛЕНИЕ ВНЕШНЕГО ВИДА (2.342.0)
   ==================================================================
   Цель — выглядеть как современные трекеры задач (ориентир — Asana):
   белая рабочая область вместо серой, светлая боковая панель с
   нейтральной подсветкой пункта, тонкие линии вместо рамок, один
   шрифт (Inter) без моноширинных цифр в интерфейсе, шрифт крупнее
   (14 px), кнопки одного вида, метки без прописных букв, панель задачи
   и окна без размытия страницы под ними.

   Подключается ПОСЛЕДНИМ (после theme.999.palette.css). Меняет токены и
   внешний вид, разметку и поведение не трогает.
   ОТКАТ: убрать одну строку @import в index.css и пересобрать
   (node tools/build-css.mjs) — вернётся прежний вид.

   Контраст текста (WCAG AA ≥ 4,5:1) посчитан для обеих тем:
     светлая: ink 16.5, ink-2 10.8, muted 6.3, faint 5.0 на #FFFFFF
              (на самом тёмном сером слое #F4F4F6 faint — 4.56);
     тёмная:  ink 14.6, ink-2 11.5, muted 7.2, faint 5.4 на #1E1F21
              (на приподнятом слое #2A2B2E faint — 4.61);
     акцент #5B4FDB на белом и белый на акценте — 5.86.
   ================================================================== */

/* ---------- Токены: светлая тема ---------- */
:root:not([data-theme="dark"]){
  --canvas:#FFFFFF; --surface:#FFFFFF; --raised:#FFFFFF;
  --chrome:#F3F3F5; --chrome-2:#F7F7F8; --well:#F6F6F8;
  --surface-2:#F4F4F6; --surface-3:#EDEDF0;
  --line:#E2E2E7; --line-2:#ECECEF; --line-3:#D5D5DC;
  --ink:#1E1F24; --ink-2:#3B3D45; --muted:#5D606B; --faint:#6C6F7A;
  --side-bg:#F7F7F8; --side-hover:#ECECEF; --side-active:#E6E6EA;
  --row-hover:#F8F8FA;
  --shadow-xs:0 1px 1px rgba(20,21,26,.03);
  --shadow-sm:0 1px 2px rgba(20,21,26,.05);
  --shadow-md:0 4px 14px -2px rgba(20,21,26,.10),0 0 0 1px rgba(20,21,26,.04);
  --shadow-lg:0 16px 40px -8px rgba(20,21,26,.18),0 0 0 1px rgba(20,21,26,.05);
  --scrim:rgba(20,21,26,.32);
}
/* ---------- Токены: тёмная тема ---------- */
:root[data-theme="dark"]{
  --canvas:#1E1F21; --surface:#1E1F21; --raised:#2A2B2E;
  --chrome:#18191B; --chrome-2:#252628; --well:#232427;
  --surface-2:#2A2B2E; --surface-3:#313236;
  --line:#3A3B3F; --line-2:#2F3034; --line-3:#46474C;
  --ink:#F1F1F3; --ink-2:#D6D7DB; --muted:#A9ABB2; --faint:#91939A;
  --side-bg:#252628; --side-hover:#2F3033; --side-active:#36373B;
  --row-hover:#242528;
  --shadow-md:0 6px 18px -4px rgba(0,0,0,.5),0 0 0 1px rgba(255,255,255,.05);
  --shadow-lg:0 20px 48px -10px rgba(0,0,0,.6),0 0 0 1px rgba(255,255,255,.06);
  --scrim:rgba(0,0,0,.5);
}
/* ---------- Общие токены ---------- */
:root{
  --t-body:14px; --t-sm:13px; --t-xs:12px; --t-micro:11px; --t-h3:14px; --t-h2:16px; --t-h1:22px; --t-display:24px;
  --sidebar-w:260px;
  --ctl-h:32px; --ctl-h-sm:28px; --ctl-h-lg:38px;
  --code:'JetBrains Mono',ui-monospace,'SF Mono',Menlo,Consolas,monospace;
  /* Цифры в интерфейсе — тем же шрифтом, что и текст, но моноширинными
     по ширине (tabular-nums), а не отдельным «кодовым» шрифтом. */
  --mono:var(--sans);
}
.due-pill,.act-time,.attach-size,.au-when,.bc-count,.cf-val,.comment-time,.dash-proj-pct,.grp-count,.inbox-time,.mono,
.pf-prog-num,.poll-num,.section-count,.sg-num,.stat-sub,.task-sub-badge,.tb-sync,.time-entry-dur,.timer-total,.tl2-count,
.tl2-day,.tl2-seccount,.wl-redist-hrs,.home-tasksec-h .cnt,.panel-sec-title .cnt,.cal-daynum,.goal-q,.dl-val,.sum-row{font-variant-numeric:tabular-nums;letter-spacing:0}
/* Код остаётся моноширинным */
.api-example,.auth-code,.comment-text code,.desc-rendered code,.rich-code,.tf-code,.tf-codes,.int-hook-url,.int-webhook-url,.int-copy,.dg-log,.dg-mono,.conflict-diff-key,.doc-area code,.cmdk-kk,.menu-kbd,.sc-keys{font-family:var(--code)}

/* ---------- База ---------- */
html,body{background:var(--canvas)}
body{font-size:var(--t-body);letter-spacing:-.003em;-webkit-font-smoothing:antialiased}
#main,.page-head{background:var(--canvas)}

/* ---------- Боковая панель ---------- */
#sidebar{background:var(--side-bg);border-right:1px solid var(--line-2)}
#sidebar .nav-item{height:32px;min-height:32px;padding:0 10px;border-radius:6px;font-size:var(--t-body);font-weight:450;color:var(--ink-2);gap:10px}
#sidebar .nav-item:hover{background:var(--side-hover);color:var(--ink)}
#sidebar .nav-item.active{background:var(--side-active);color:var(--ink);font-weight:550;box-shadow:none}
#sidebar .nav-item.active::before{display:none}
#sidebar .side-group-title{font-size:var(--t-xs);font-weight:600;color:var(--faint);letter-spacing:0;text-transform:none}
#sidebar .side-create{height:34px;min-height:34px;border-radius:8px;font-weight:600;box-shadow:none}
#sidebar .side-foot{border-top:1px solid var(--line-2)}

/* ---------- Верхняя панель ---------- */
.topbar,#topbar{background:var(--canvas);border-bottom:1px solid var(--line-2);box-shadow:none}
.tb-search,.topbar input[type="search"]{background:var(--surface-2);border:1px solid transparent;border-radius:8px}
.tb-search:focus-within{background:var(--canvas);border-color:var(--line)}
.tb-sync{font-size:var(--t-xs);font-weight:500}

/* ---------- Шапка страницы и вкладки ---------- */
.page-head{padding-top:20px}
.ph-title{font-size:var(--t-display);font-weight:600;letter-spacing:-.015em}
.ph-eyebrow{font-size:var(--t-xs);font-weight:500;color:var(--faint)}
.ph-emoji{border-radius:8px}
.tabs{margin-top:14px;border-bottom:1px solid var(--line-2);gap:4px}
.tab{padding:8px 10px 10px;font-size:var(--t-body);font-weight:500;color:var(--muted)}
.tab:hover{color:var(--ink)}
.tab.active{color:var(--ink);font-weight:550;border-bottom-color:var(--ink)}
:root[data-theme="dark"] .tab.active{border-bottom-color:var(--ink)}

/* ---------- Кнопки ---------- */
.btn{border-radius:6px;font-weight:500;font-size:var(--t-sm);box-shadow:none}
.btn-primary{background:var(--accent);color:var(--accent-fg);box-shadow:none}
.btn-primary:hover{background:var(--accent-600)}
:root[data-theme="dark"] .btn-primary:hover{background:#7F70FF}
.btn-ghost{background:var(--canvas);border:1px solid var(--line);color:var(--ink-2);box-shadow:none}
.btn-ghost:hover{background:var(--surface-2);border-color:var(--line-3);color:var(--ink)}

/* ---------- Список задач ---------- */
.list-colhead{border-bottom:1px solid var(--line-2);font-size:var(--t-xs);font-weight:500;color:var(--muted)}
.task-row{min-height:40px;border-bottom:1px solid var(--line-2);border-radius:0;background:transparent}
.task-row:hover{background:var(--row-hover);box-shadow:none;border-bottom-color:var(--line-2)}
.task-name{font-size:var(--t-body);font-weight:400;color:var(--ink)}
/* Название — главное в строке: значки рядом с ним сжимаются первыми,
   а не название (раньше от «Финализировать…» оставалось «Ф…»). */
.task-main{min-width:0}
.task-main .task-name{flex:1 1 auto;min-width:min(9em,55%)}
/* Значки «ждёт другую», «веха», «повтор» в строке — только иконкой (как
   у Asana); полное название — в панели задачи. */
.task-main .blocked-badge,.task-main .ms-badge,.task-main .recur-badge{flex:0 0 auto;font-size:0;gap:0;padding:3px 5px;line-height:0}
.task-main .blocked-badge svg,.task-main .ms-badge svg,.task-main .recur-badge svg{width:12px;height:12px}
.task-main .task-sub-badge{flex:0 0 auto;white-space:nowrap}
.section-head{padding:18px 12px 6px}
.section-head .sec-name,.section-name{font-size:var(--t-h2);font-weight:600}
.sum-row{border-top:none;min-height:30px;font-size:var(--t-xs);color:var(--faint)}
.sum-label{text-transform:none;letter-spacing:0;font-weight:500}
.status-tag,.prio-tag{border-radius:999px;font-size:var(--t-xs);font-weight:500;padding:2px 9px}
/* Срок — текстом, как у Asana: без «ярлыка», цвет говорит сам */
.due-pill{font-size:var(--t-sm);font-weight:450;background:transparent!important;padding:0;color:var(--ink-2)}
.due-pill.today{color:var(--ok)}
.due-pill.over,.due-pill.overdue,.due-pill.late{color:var(--danger)}

/* ---------- Доска ---------- */
.board-col{background:var(--well);border:none;border-radius:12px}
.board-col .card,.board-wrap .card{background:var(--raised);border:1px solid var(--line-2);border-radius:10px;box-shadow:var(--shadow-xs)}
.board-col .card:hover,.board-wrap .card:hover{border-color:var(--line-3);box-shadow:var(--shadow-md)}

/* ---------- Панель задачи ---------- */
#panel{background:var(--canvas)}
.panel-top{background:var(--canvas);border-bottom:1px solid var(--line-2);backdrop-filter:none;-webkit-backdrop-filter:none}
.panel-name{font-size:22px;font-weight:600;letter-spacing:-.012em}
.panel-sec-title{font-size:var(--t-body);font-weight:600;color:var(--ink)}
.field-lbl,.field-grid-side .field-lbl{text-transform:none;letter-spacing:0;font-size:var(--t-sm);font-weight:500;color:var(--muted)}
.panel-side-more-title{text-transform:none;letter-spacing:0;font-size:var(--t-sm);font-weight:600;color:var(--ink-2)}
.panel-divider{border-color:var(--line-2);background:var(--line-2)}

/* ---------- Окна, меню, подложки ---------- */
.overlay,.modal-back,.cmdk-overlay,.auto-overlay{background:var(--scrim);backdrop-filter:none;-webkit-backdrop-filter:none}
.modal{border:none;border-radius:12px;box-shadow:var(--shadow-lg);background:var(--raised)}
.modal-title{font-size:18px;font-weight:600}
.form-input{border-radius:6px;border-color:var(--line);background:var(--canvas)}
.form-input:hover{border-color:var(--line-3)}
.menu{border:1px solid var(--line-2);border-radius:10px;box-shadow:var(--shadow-md);background:var(--raised)}
.menu-item{border-radius:6px;font-size:var(--t-sm)}

/* ---------- Главная, входящие ---------- */
.home-tasksec-h,.int-cat-title,.side-plan-name{text-transform:none;letter-spacing:0}
.inbox-item{border-radius:8px}
.inbox-item:hover{background:var(--row-hover)}

/* ---------- Телефон ---------- */
@media (max-width:760px){
  .task-row{background:var(--raised);border:1px solid var(--line-2);border-radius:10px}
  /* Кружок выполнения остаётся кругом (цель касания прежняя), не сжимается в овал */
  .task-row .task-main{overflow:visible}
  .task-row .task-check{flex:0 0 auto;width:22px;height:22px;min-width:22px;min-height:22px;padding:0;margin:0 2px 0 0;box-sizing:border-box;position:relative}
  /* цель касания остаётся 44×44 — невидимой областью вокруг кружка */
  .task-row .task-check::after{content:"";position:absolute;inset:-11px}
  .task-row .row-sel,.task-row .row-caret.ph{display:none}
  /* «Итого» — строка итогов, а не карточка */
  .task-row.sum-row{background:transparent;border:none;border-radius:0;padding:4px 14px;margin:0}
  .ph-title{font-size:21px}
}
@media (prefers-reduced-motion:reduce){*{scroll-behavior:auto}}

/* Значки подзадач и комментариев не наезжают на колонку исполнителя */
@media (min-width:761px){.task-row .task-main{overflow:hidden}}
/* Одна кнопка «Создать», как у Asana: при открытой боковой панели на
   широком экране — только в ней; при свёрнутой и на телефоне — в шапке. */
@media (min-width:1024px){
  #app:not(.collapsed) .tb-create-wrap{display:none}
}

/* Карточка доски: название переносится до трёх строк (как у Asana),
   значки — иконкой, отметка выбора — только по наведению или если выбрана */
.board-wrap .card .card-title,.board-col .card .card-title{flex:1 1 auto;min-width:0;white-space:normal;overflow:hidden;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;line-height:1.4;font-weight:450}
.board-wrap .card .blocked-badge,.board-wrap .card .ms-badge,.board-wrap .card .recur-badge{flex:0 0 auto;font-size:0;gap:0;padding:3px 5px;line-height:0}
.board-wrap .card .blocked-badge svg,.board-wrap .card .ms-badge svg,.board-wrap .card .recur-badge svg{width:12px;height:12px}
@media (hover:hover){.board-wrap .card .card-sel:not(.on){opacity:0;width:0;margin:0;border-width:0;transition:opacity var(--dur-fast)}
  .board-wrap .card:hover .card-sel:not(.on),.board-wrap .card:focus-within .card-sel:not(.on){opacity:1;width:auto;margin:revert;border-width:revert}}
/* Боковая панель на компьютере — плоская, отделена линией, без тени */
@media (min-width:769px){#sidebar{box-shadow:none}}
/* Рабочая область не «парит» над боковой панелью: вместо тени — та же
   тонкая линия, что у панели (как у Asana) */
@media (min-width:769px){#workspace,.workspace{box-shadow:-1px 0 0 var(--line-2)!important}}

/* 2.344.0: панель форматирования и новая разметка (чек-лист, цитата, зачёркнутый) */
.md-tb{display:flex;align-items:center;gap:2px;flex-wrap:wrap;padding:4px;margin-bottom:6px;border:1px solid var(--line-2);border-radius:8px;background:var(--surface-2)}
.md-tb-btn{min-width:28px;height:28px;padding:0 7px;border:0;border-radius:6px;background:transparent;color:var(--ink-2);font:600 13px/1 var(--sans);cursor:pointer;display:inline-flex;align-items:center;justify-content:center}
.md-tb-btn:hover{background:var(--surface-3);color:var(--ink)}
.md-tb-btn:focus-visible{outline:none;box-shadow:var(--ring)}
.md-tb-btn.md-italic{font-style:italic;font-family:Georgia,serif}
.md-tb-btn.md-strike{text-decoration:line-through}
.md-tb-btn.md-code,.md-tb-btn.md-codeblock{font-family:var(--code);font-size:12px}
.md-tb-sep{width:1px;height:18px;background:var(--line);margin:0 4px}
.comment-input-wrap .md-tb{margin-bottom:4px;padding:2px}
.comment-input-wrap .md-tb-btn{height:26px;min-width:26px}
@media (max-width:760px){.md-tb-btn{min-width:36px;height:36px}}
.rich-check{list-style:none;padding-left:0;margin:6px 0}
.rich-check .rc-item{display:flex;align-items:flex-start;gap:8px;padding:2px 0}
.rich-check .rc-box{width:16px;height:16px;margin:3px 0 0;accent-color:var(--ok);cursor:pointer;flex:none}
.rich-check .rc-box:disabled{cursor:default}
.rich-check .rc-item.done>span{color:var(--muted);text-decoration:line-through}
.rich-quote{margin:6px 0;padding:4px 0 4px 12px;border-left:3px solid var(--line-3);color:var(--ink-2)}
del{color:var(--muted)}

/* 2.345.0: согласование (значок статуса, блок решения) и дубликат */
.appr-badge{display:inline-flex;align-items:center;gap:4px;padding:2px 7px;border-radius:999px;font-size:var(--t-xs);font-weight:500;white-space:nowrap;background:var(--surface-3);color:var(--ink-2)}
.appr-badge.pending{background:var(--warn-soft);color:var(--warn)}
.appr-badge.approved{background:var(--ok-soft);color:var(--ok)}
.appr-badge.changes{background:var(--info-soft);color:var(--info)}
.appr-badge.rejected{background:var(--danger-soft);color:var(--danger)}
.task-main .appr-badge,.board-wrap .card .appr-badge{flex:0 0 auto}
.appr-block{border:1px solid var(--line-2);border-radius:10px;padding:12px 14px;margin:6px 0 4px;background:var(--surface-2)}
.appr-block.approved{border-color:var(--ok-line);background:var(--ok-soft)}
.appr-block.rejected{border-color:var(--danger-line);background:var(--danger-soft)}
.appr-block.changes{border-color:var(--info-line);background:var(--info-soft)}
.appr-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.appr-who{color:var(--muted);font-size:var(--t-sm)}
.appr-btns{display:flex;gap:6px;flex-wrap:wrap;margin-top:10px}
.appr-btns .btn.on{box-shadow:inset 0 0 0 2px var(--accent)}
.appr-btns .appr-rej{color:var(--danger)}
.dup-banner{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:10px 12px;margin-bottom:12px;border-radius:10px;background:var(--surface-2);border:1px solid var(--line-2);color:var(--ink-2);font-size:var(--t-sm)}
.dup-banner>span{flex:1 1 200px}
.dup-list{max-height:320px;overflow-y:auto}
.dup-item .dup-t{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.menu-note{padding:8px 12px;font-size:var(--t-sm);color:var(--muted);max-width:280px}
.task-main .appr-badge{font-size:0;gap:0;padding:3px 5px;line-height:0}
.task-main .appr-badge svg{width:12px;height:12px}

/* 2.346.0: панель расширенного поиска */
.adv-bar{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin:14px 0 4px}
.adv-text{display:flex;align-items:center;gap:6px;flex:1 1 240px;max-width:360px;height:32px;padding:0 10px;border:1px solid var(--line);border-radius:6px;background:var(--canvas);color:var(--muted)}
.adv-text:focus-within{border-color:var(--accent);box-shadow:var(--ring)}
.adv-q{border:0;outline:0;background:transparent;color:var(--ink);font:inherit;flex:1;min-width:0}
.adv-pill{display:inline-flex;align-items:center;gap:4px;height:32px;padding:0 10px;border:1px solid var(--line);border-radius:999px;background:var(--canvas);color:var(--ink-2);font:500 var(--t-sm)/1 var(--sans);cursor:pointer;max-width:260px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.adv-pill:hover{background:var(--surface-2)}
.adv-pill.on{background:var(--accent-soft);border-color:var(--accent-line);color:var(--accent-700)}
.adv-pill.ghost{border-color:transparent}
.adv-pill:focus-visible{outline:none;box-shadow:var(--ring)}
.adv-range{display:inline-flex;align-items:center;gap:6px}.adv-range .form-input{width:auto;height:32px}
.adv-spacer{flex:1}
.adv-opts{max-height:320px;overflow-y:auto}
.adv-cb{width:16px;height:16px;border:1.5px solid var(--line-3);border-radius:4px;display:inline-flex;align-items:center;justify-content:center;flex:none}
.adv-cb.on{background:var(--accent);border-color:var(--accent);color:var(--accent-fg)}
.adv-ol{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* 2.347.0: обзор проекта — описание, ресурсы, вехи, участники */
.ov-card .chart-title{display:flex;align-items:center;gap:6px}
.ov-brief{cursor:text;border-radius:8px;padding:6px 8px;margin:-6px -8px}
.ov-brief:hover{background:var(--surface-2)}
.ov-brief-empty{display:block;width:100%;text-align:left;font:inherit;cursor:pointer}
.ov-brief-area{width:100%;min-height:120px;resize:vertical;line-height:1.55}
.ov-res{display:flex;align-items:center;gap:8px;padding:8px 0;border-top:1px solid var(--line-2);min-width:0}
.ov-res a{color:var(--ink);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ov-res a:hover{color:var(--accent);text-decoration:underline}
.ov-res-host{color:var(--faint);font-size:var(--t-xs);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ov-res-del{opacity:.6}.ov-res:hover .ov-res-del,.ov-res-del:focus-visible{opacity:1}
.ov-add{margin-top:10px}
.ov-ms{display:flex;align-items:center;gap:10px;padding:8px 0;border-top:1px solid var(--line-2);cursor:pointer}
.ov-ms:hover .ov-ms-t{color:var(--accent)}
.ov-ms-ic{color:var(--warn);font-size:13px}.ov-ms.done .ov-ms-ic{color:var(--ok)}
.ov-ms-t{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ov-ms.done .ov-ms-t{color:var(--muted);text-decoration:line-through}
.ov-cnt{color:var(--faint);font-weight:500}
.ov-manage{margin-left:auto}
.ov-members{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:10px;margin-top:6px}
.ov-mem{display:flex;align-items:center;gap:10px;min-width:0}
.ov-mem-t{min-width:0}.ov-mem-n{font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ov-mem-r{color:var(--muted);font-size:var(--t-xs)}
@media (max-width:760px){.ov-card[style*="span 6"]{grid-column:1/-1!important}}

/* 2.348.0: вкладки-представления проекта */
.tabs{overflow-x:auto;scrollbar-width:none}.tabs::-webkit-scrollbar{display:none}
.tab-view{max-width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tab-add{padding-left:8px;padding-right:8px;color:var(--faint)}
.tab-add:hover{color:var(--ink)}
.tab-add:focus-visible{outline:none;box-shadow:var(--ring);border-radius:6px}

/* 2.349.0: проверка макетов */
.proof-btn{display:inline-flex;align-items:center;gap:4px;height:26px;padding:0 8px;border:1px solid var(--line);border-radius:999px;background:var(--canvas);color:var(--ink-2);font:500 var(--t-xs)/1 var(--sans);cursor:pointer;white-space:nowrap;margin-right:4px}
.proof-btn:hover{border-color:var(--accent);color:var(--accent)}
.proof-modal{width:min(1200px,96vw);max-width:96vw}
.proof-body{display:grid;grid-template-columns:minmax(0,1fr) 280px;gap:16px;max-height:78vh}
.proof-stage-wrap{overflow:auto;background:var(--well);border-radius:10px;display:flex;align-items:flex-start;justify-content:center;padding:12px}
.proof-stage{position:relative;display:inline-block;line-height:0;max-width:100%}
.proof-stage.can{cursor:crosshair}
.proof-stage img{max-width:100%;height:auto;display:block;border-radius:6px;user-select:none}
.proof-pin{position:absolute;transform:translate(-50%,-50%);width:26px;height:26px;border-radius:50%;border:2px solid #fff;background:var(--accent);color:#fff;font:700 12px/1 var(--sans);display:inline-flex;align-items:center;justify-content:center;box-shadow:0 2px 6px rgba(0,0,0,.35);cursor:pointer;padding:0}
.proof-pin.done{background:var(--ok)}
.proof-pin.draft{background:var(--warn);pointer-events:none}
.proof-pin.static{position:static;transform:none;flex:none;box-shadow:none;border:0}
.proof-pin:focus-visible{outline:none;box-shadow:0 0 0 3px var(--accent-soft),0 2px 6px rgba(0,0,0,.35)}
.proof-draft{position:absolute;line-height:1.4}
.proof-draft .proof-pin{position:absolute;left:0;top:0}
.proof-pop{position:absolute;left:18px;top:18px;width:260px;background:var(--raised);border:1px solid var(--line-2);border-radius:10px;box-shadow:var(--shadow-lg);padding:10px;z-index:2;cursor:default}
.proof-pop-btns{display:flex;justify-content:flex-end;gap:6px;margin-top:8px}
.proof-side{overflow-y:auto}
.proof-side-h{font-weight:600;margin-bottom:8px}.proof-side-h .cnt{color:var(--faint);font-weight:500}
.proof-li{display:flex;align-items:flex-start;gap:8px;padding:8px;border-radius:8px;cursor:pointer;line-height:1.4}
.proof-li:hover{background:var(--surface-2)}
.proof-li.done .proof-li-t{color:var(--muted);text-decoration:line-through}
.proof-empty{color:var(--muted);font-size:var(--t-sm);line-height:1.5}
@media (max-width:860px){.proof-body{grid-template-columns:1fr;max-height:none}.proof-pop{left:-120px;width:240px}}
.proof-modal .modal-title{display:flex;align-items:center;gap:8px;min-width:0}

/* 2.350.0: библиотека полей, отчёт о статусе портфеля и цели */
.fld-lib{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:999px;background:var(--accent-soft);color:var(--accent-700);font-size:var(--t-xs);font-weight:500;white-space:nowrap}
.flib-list{display:grid;gap:2px}
.flib-row{display:flex;align-items:center;gap:8px;padding:6px 0;border-bottom:1px solid var(--line-2)}
.flib-row .fld-name{flex:0 1 auto;font-weight:500}.flib-row .fld-type{flex:1;color:var(--muted);font-size:var(--t-xs)}
.flib-empty{color:var(--muted);font-size:var(--t-sm);padding:4px 0 8px;line-height:1.5}
.stx-card{margin:12px 0 4px;padding:12px 14px;border:1px solid var(--line-2);border-radius:10px;background:var(--surface-2)}
.stx-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.stx-lbl{display:inline-flex;align-items:center;gap:6px;font-weight:600}
.stx-none{color:var(--muted);font-size:var(--t-sm)}
.stx-meta{display:inline-flex;align-items:center;gap:6px;color:var(--muted);font-size:var(--t-sm)}
.stx-sp{flex:1}
.stx-text{margin-top:8px;color:var(--ink-2);font-size:var(--t-sm);line-height:1.55}
.stx-h-item{padding:10px 0;border-bottom:1px solid var(--line-2)}.stx-h-item:last-child{border-bottom:0}
.goal-st-btn{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;margin-left:4px;border:1px solid var(--line);border-radius:6px;background:var(--canvas);color:var(--muted);cursor:pointer;vertical-align:middle}
.goal-st-btn:hover{color:var(--accent);border-color:var(--accent)}
.goal-q .pf-status{margin-left:6px;font-size:var(--t-micro)}
.goal-st-text{margin:4px 0 6px;color:var(--muted);font-size:var(--t-sm);line-height:1.45}

/* 2.351.0: вкладка «Процесс» */
.wf-wrap{padding:8px 0 40px;display:grid;gap:28px}
.wf-h{font-size:var(--t-h2);font-weight:600;margin:0}
.wf-h-row{display:flex;align-items:center;gap:12px;justify-content:space-between}
.wf-sub{color:var(--muted);font-size:var(--t-sm);margin:4px 0 12px}
.wf-ins{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:12px}
.wf-in{border:1px solid var(--line-2);border-radius:12px;padding:14px;background:var(--raised);display:flex;flex-direction:column;gap:8px}
.wf-in.on{border-color:var(--ok-line)}
.wf-in-h{display:flex;align-items:center;gap:8px}.wf-in-h b{flex:1}
.wf-in p{margin:0;color:var(--muted);font-size:var(--t-sm);line-height:1.5;flex:1}
.wf-in .btn{align-self:flex-start}
.wf-state{font-size:var(--t-xs);font-weight:500;padding:2px 8px;border-radius:999px;background:var(--surface-3);color:var(--muted);white-space:nowrap}
.wf-state.on{background:var(--ok-soft);color:var(--ok)}
.wf-cols{display:flex;align-items:stretch;gap:6px;overflow-x:auto;padding-bottom:6px}
.wf-col{flex:0 0 220px;border-radius:12px;background:var(--well);padding:12px;display:flex;flex-direction:column;gap:8px}
.wf-col-h{display:flex;align-items:center;gap:8px;font-weight:600}.wf-col-n{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.wf-cnt{color:var(--faint);font-weight:500;font-size:var(--t-sm)}
.wf-col-sub{color:var(--muted);font-size:var(--t-xs)}
.wf-rule{display:flex;gap:6px;align-items:flex-start;padding:8px;border-radius:8px;background:var(--raised);border:1px solid var(--line-2);font-size:var(--t-sm);line-height:1.4}
.wf-rule svg{flex:none;margin-top:2px;color:var(--accent)}
.wf-norule{color:var(--faint);font-size:var(--t-sm);padding:4px 0}
.wf-add{align-self:flex-start;display:inline-flex;align-items:center;gap:4px;border:1px dashed var(--line-3);background:transparent;border-radius:6px;padding:4px 8px;color:var(--muted);font:500 var(--t-xs)/1.2 var(--sans);cursor:pointer}
.wf-add:hover{color:var(--accent);border-color:var(--accent)}
.wf-arrow{display:flex;align-items:center;color:var(--faint);flex:none}
.wf-autos{display:grid;gap:8px}
.wf-auto{display:flex;align-items:center;gap:12px;padding:10px 12px;border:1px solid var(--line-2);border-radius:10px;background:var(--raised)}
.wf-auto.off{opacity:.7}
.wf-auto-ic{width:30px;height:30px;border-radius:8px;background:var(--accent-soft);color:var(--accent-700);display:flex;align-items:center;justify-content:center;flex:none}
.wf-auto-t{flex:1;min-width:0}.wf-auto-n{font-weight:500}.wf-auto-d{color:var(--muted);font-size:var(--t-xs)}
.wf-switch{position:relative;display:inline-block;width:36px;height:20px;flex:none;cursor:pointer}
.wf-switch input{position:absolute;opacity:0;inset:0;margin:0;cursor:pointer;z-index:1}
.wf-switch span{position:absolute;inset:0;border-radius:999px;background:var(--line-3);transition:background var(--dur-fast)}
.wf-switch span::after{content:"";position:absolute;left:2px;top:2px;width:16px;height:16px;border-radius:50%;background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.3);transition:transform var(--dur-fast)}
.wf-switch input:checked+span{background:var(--ok)}
.wf-switch input:checked+span::after{transform:translateX(16px)}
.wf-switch input:focus-visible+span{box-shadow:var(--ring)}
.wf-empty{color:var(--muted);font-size:var(--t-sm);padding:12px;border:1px dashed var(--line);border-radius:10px}

/* 2.352.0: работа без сети */
#offlineBar{position:fixed;left:50%;top:calc(env(safe-area-inset-top,0px) + 62px);transform:translateX(-50%);z-index:95;max-width:min(560px,92vw);padding:8px 14px;border-radius:999px;background:var(--ink);color:var(--canvas);font:500 var(--t-sm)/1.35 var(--sans);box-shadow:var(--shadow-md);text-align:center;pointer-events:none}
.tb-sync.off .tb-sync-lbl,.tb-sync.err .tb-sync-lbl{color:var(--warn)}
