/* ============================================================
   SEObox Workspace — светлая тема личного кабинета
   ------------------------------------------------------------
   Слой ПОЛНОСТЬЮ ограничен областью кабинета: каждое правило живёт
   внутри .ws-shell. Публичная часть сайта использует те же имена
   переменных в своём тёмном оформлении, и без этой изоляции светлые
   значения протекли бы на главную страницу.

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

.ws-shell {
  /* Поверхности */
  --ws-bg:        #F7F9FC;   /* фон рабочей области */
  --ws-surface:   #FFFFFF;   /* карточки */
  --ws-surface-2: #F1F5F9;   /* вложенные блоки, наведение */
  --ws-border:    #E5E7EF;   /* тонкие границы */
  --ws-border-2:  #D6DEE9;   /* границы активных элементов */

  /* Текст */
  --ws-text:      #0F172A;
  --ws-text-2:    #64748B;   /* вторичный */
  --ws-text-3:    #94A3B8;   /* подписи */

  /* Фирменный синий берём из общей темы, чтобы кабинет и сайт
     не разошлись по бренду при смене акцента. */
  --ws-primary:      #6D5AE6;   /* индиго/фиолетовый акцент референса */
  --ws-primary-soft: rgba(109, 90, 230, 0.10);

  /* Смысловые цвета */
  --ws-green:  #16A34A;  --ws-green-soft:  rgba(22, 163, 74, 0.10);
  --ws-orange: #EA580C;  --ws-orange-soft: rgba(234, 88, 12, 0.10);
  --ws-red:    #DC2626;  --ws-red-soft:    rgba(220, 38, 38, 0.10);
  --ws-purple: #7C3AED;  --ws-purple-soft: rgba(124, 58, 237, 0.10);
  --ws-cyan:   #0891B2;  --ws-cyan-soft:   rgba(8, 145, 178, 0.10);

  /* Тени мягкие: в светлой теме глубина задаётся почти незаметными
     слоями, резкая тень сразу читается как чужеродная. */
  --ws-shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.04);
  --ws-shadow:    0 1px 3px rgba(15, 23, 42, 0.06), 0 1px 2px rgba(15, 23, 42, 0.04);
  --ws-shadow-lg: 0 10px 30px rgba(15, 23, 42, 0.10), 0 2px 8px rgba(15, 23, 42, 0.05);

  --ws-radius:    13px;
  --ws-radius-sm: 8px;
  --ws-radius-lg: 16px;

  --ws-sidebar-w:  220px;   /* по референсу: 215–225 */
  --ws-sidebar-wc:  68px;   /* свёрнутое состояние */
  --ws-topbar-h:    66px;   /* по референсу: 64–70 */

  background: var(--ws-bg);
  color: var(--ws-text);
  min-height: 100vh;
}

/* ─── Оболочка ───
   Боковое меню занимает ВСЮ высоту окна от самого верха, включая область
   логотипа. Шапка начинается справа от него, а не проходит поверх всей
   ширины: иначе логотип оказывается в шапке, меню выглядит приставленным
   сбоку, и два элемента читаются как разные интерфейсы.

   Смещение задаётся одной переменной --ws-off: при сворачивании меняется
   только она, и шапка с содержимым сдвигаются согласованно. Раньше это
   пришлось бы описывать в трёх местах. */
.ws-shell { --ws-off: var(--ws-sidebar-w); display: block; }
.ws-shell[data-collapsed="1"] { --ws-off: var(--ws-sidebar-wc); }

.ws-sidebar {
  position: fixed; left: 0; top: 0; bottom: 0; z-index: 60;
  width: var(--ws-off); height: 100vh; height: 100dvh;
  background: var(--ws-surface);
  border-right: 1px solid var(--ws-border);
  display: flex; flex-direction: column;
  overflow-y: auto; overflow-x: hidden;
  transition: width .18s ease;
}
/* Шапка лежит В РАЗМЕТКЕ вне .ws-shell, поэтому переменная --ws-off до неё
   не доходит: её собственное смещение задаём от корня. Значение то же и
   переключается тем же признаком свёрнутости на оболочке. */
.ws-topbar {
  position: fixed; top: 0; right: 0; z-index: 50;
  left: var(--ws-sidebar-w); width: auto;
  height: var(--ws-topbar-h);
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: saturate(180%) blur(8px);
  border-bottom: 1px solid var(--ws-border);
  display: flex; align-items: center; gap: 12px;
  transition: left .18s ease;
}
.ws-content {
  margin-left: var(--ws-off);
  padding: 24px;
  padding-top: calc(var(--ws-topbar-h) + 24px);
  max-width: 1600px;
  /* min-width:0 обязателен: без него длинное содержимое растягивает
     область и появляется горизонтальная прокрутка. */
  min-width: 0;
  transition: margin-left .18s ease;
}

/* ─── Меню ─── */
.ws-nav-group { padding: 14px 12px 4px; }
.ws-nav-group-title {
  font-size: 11px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ws-text-3);
  padding: 0 10px 6px;
}
.ws-shell[data-collapsed="1"] .ws-nav-group-title { display: none; }

.ws-nav-item {
  display: flex; align-items: center; gap: 10px;
  width: 100%; padding: 9px 10px; margin-bottom: 2px;
  border: 0; background: transparent; cursor: pointer;
  border-radius: var(--ws-radius-sm);
  color: var(--ws-text-2); font-size: 14px; font-weight: 500;
  text-align: left; position: relative;
  transition: background .15s, color .15s;
}
.ws-nav-item:hover { background: var(--ws-surface-2); color: var(--ws-text); }
.ws-nav-item[aria-current="page"] { background: var(--ws-primary-soft); color: var(--ws-primary); font-weight: 600; }
.ws-nav-item .ic { width: 18px; height: 18px; flex: 0 0 18px; }
.ws-nav-item-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ws-shell[data-collapsed="1"] .ws-nav-item { justify-content: center; padding: 10px; }
.ws-shell[data-collapsed="1"] .ws-nav-item-label { display: none; }

/* Подсказка в свёрнутом виде. Показывается и при наведении, и при фокусе —
   иначе свёрнутое меню недоступно с клавиатуры. */
.ws-shell[data-collapsed="1"] .ws-nav-item::after {
  content: attr(data-label);
  position: absolute; left: calc(100% + 8px); top: 50%;
  transform: translateY(-50%);
  background: var(--ws-text); color: #fff;
  font-size: 12px; padding: 5px 9px; border-radius: 6px;
  white-space: nowrap; opacity: 0; pointer-events: none;
  transition: opacity .12s; z-index: 60;
}
.ws-shell[data-collapsed="1"] .ws-nav-item:hover::after,
.ws-shell[data-collapsed="1"] .ws-nav-item:focus-visible::after { opacity: 1; }

.ws-nav-footer { margin-top: auto; border-top: 1px solid var(--ws-border); padding: 10px 12px 14px; }

/* ─── Карточки и сетки ─── */
.ws-card {
  background: var(--ws-surface);
  border: 1px solid var(--ws-border);
  border-radius: var(--ws-radius);
  box-shadow: var(--ws-shadow-sm);
  padding: 18px;
}
.ws-card-title { font-size: 15px; font-weight: 700; margin-bottom: 4px; }
.ws-card-sub { font-size: 13px; color: var(--ws-text-2); }

.ws-grid { display: grid; gap: 14px; }
/* auto-fit + minmax: колонки подстраиваются сами, без списка брейкпоинтов
   на каждую ширину. minmax начинается с 0, иначе на 320 px карточка
   шире экрана и появляется горизонтальная прокрутка. */
.ws-grid-kpi   { grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); }
.ws-grid-cards { grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr)); }
.ws-grid-tools { grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr)); }

/* ─── Карточка возможности ─── */
.ws-tool-card {
  display: flex; flex-direction: column; gap: 6px;
  background: var(--ws-surface);
  border: 1px solid var(--ws-border);
  border-radius: var(--ws-radius);
  padding: 14px; text-align: left; cursor: pointer;
  transition: border-color .15s, box-shadow .15s, transform .15s;
  min-width: 0;
}
.ws-tool-card:hover { border-color: var(--ws-border-2); box-shadow: var(--ws-shadow); transform: translateY(-1px); }
.ws-tool-card:focus-visible { outline: 2px solid var(--ws-primary); outline-offset: 2px; }
.ws-tool-card-name {
  font-size: 14px; font-weight: 600; color: var(--ws-text);
  /* Длинные названия вроде «Разбор ниши конкурентов» переносятся,
     а не выталкивают карточку за пределы сетки. */
  overflow-wrap: anywhere; word-break: break-word;
}
.ws-tool-card-desc {
  font-size: 13px; color: var(--ws-text-2); line-height: 1.45;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.ws-badge {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 11px; font-weight: 600; padding: 2px 7px; border-radius: 999px;
  background: var(--ws-surface-2); color: var(--ws-text-2);
}
.ws-badge.ai   { background: var(--ws-purple-soft); color: var(--ws-purple); }
.ws-badge.ok   { background: var(--ws-green-soft);  color: var(--ws-green); }
.ws-badge.warn { background: var(--ws-orange-soft); color: var(--ws-orange); }
.ws-badge.crit { background: var(--ws-red-soft);    color: var(--ws-red); }
.ws-badge.data { background: var(--ws-cyan-soft);   color: var(--ws-cyan); }

/* ─── Пусто / ошибка / загрузка ─── */
.ws-empty, .ws-error {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  padding: 40px 24px; gap: 8px;
  background: var(--ws-surface);
  border: 1px dashed var(--ws-border-2);
  border-radius: var(--ws-radius);
}
.ws-empty-title, .ws-error-title { font-size: 15px; font-weight: 700; }
.ws-empty-text, .ws-error-text { font-size: 13px; color: var(--ws-text-2); max-width: 380px; }
.ws-error { border-style: solid; border-color: var(--ws-red-soft); }

.ws-skeleton {
  background: linear-gradient(90deg, var(--ws-surface-2) 25%, #E9EEF5 37%, var(--ws-surface-2) 63%);
  background-size: 400% 100%;
  animation: ws-shimmer 1.3s ease infinite;
  border-radius: var(--ws-radius-sm);
}
/* Высота задаётся заранее, чтобы после загрузки содержимое не прыгало. */
.ws-skeleton-line { height: 12px; margin-bottom: 8px; }
.ws-skeleton-card { height: 96px; }
@keyframes ws-shimmer { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }
@media (prefers-reduced-motion: reduce) {
  .ws-skeleton { animation: none; }
  .ws-tool-card:hover { transform: none; }
}

/* ─── Командная палитра ─── */
.cmd-overlay {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(15, 23, 42, 0.35);
  display: none; align-items: flex-start; justify-content: center;
  padding: 12vh 16px 16px;
}
.cmd-overlay.open { display: flex; }
.cmd-box {
  width: 100%; max-width: 620px;
  background: #fff; border: 1px solid var(--ws-border, #E5EAF1);
  border-radius: 14px; box-shadow: 0 20px 60px rgba(15, 23, 42, 0.25);
  overflow: hidden; display: flex; flex-direction: column; max-height: 70vh;
}
.cmd-head { display: flex; align-items: center; gap: 10px; padding: 14px 16px; border-bottom: 1px solid #E5EAF1; }
.cmd-head .ic { width: 18px; height: 18px; color: #64748B; }
.cmd-input { flex: 1; border: 0; outline: 0; font-size: 15px; color: #0F172A; background: transparent; min-width: 0; }
.cmd-kbd, .cmd-foot kbd {
  font: inherit; font-size: 11px; padding: 2px 6px;
  border: 1px solid #E5EAF1; border-bottom-width: 2px; border-radius: 5px; color: #64748B; background: #F7F9FC;
}
.cmd-list { overflow-y: auto; padding: 6px; }
.cmd-group { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: #94A3B8; padding: 10px 10px 4px; }
.cmd-item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 9px 10px; border: 0; background: transparent; border-radius: 8px;
  cursor: pointer; text-align: left; font-size: 14px; color: #0F172A; min-width: 0;
}
.cmd-item:hover, .cmd-item.active { background: #F1F5F9; }
.cmd-item .ic { width: 16px; height: 16px; flex: 0 0 16px; color: #64748B; }
.cmd-item-t { font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cmd-item-d { color: #94A3B8; font-size: 12px; margin-left: auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 45%; }
.cmd-empty { padding: 28px 16px; text-align: center; color: #64748B; font-size: 13px; }
.cmd-foot { display: flex; gap: 14px; align-items: center; padding: 9px 14px; border-top: 1px solid #E5EAF1; font-size: 12px; color: #94A3B8; }
.cmd-foot span:last-child { margin-left: auto; }

/* ─── Планшет и телефон ─── */
/* Порог приведён к 1199: до этой ширины кабинет работает в планшетном
   режиме с выдвижным меню. Значение 1024 осталось от прежней раскладки
   и создавало третью границу поведения посреди планшетного диапазона. */
@media (max-width: 1199px) {
  .ws-content { padding: 18px; }
  .ws-grid-tools { grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); }
}
@media (max-width: 767px) {
  /* Сайдбар становится выдвижной панелью: в сетке колонки для него больше
     нет, иначе на узком экране он съедал бы половину ширины. */
  .ws-shell { grid-template-columns: 1fr; grid-template-areas: "topbar" "content"; }
  .ws-sidebar {
    position: fixed; left: 0; top: 0; bottom: 0; z-index: 120;
    width: min(280px, 84vw); height: 100dvh;
    transform: translateX(-100%); transition: transform .22s ease;
    box-shadow: var(--ws-shadow-lg);
  }
  .ws-sidebar.open { transform: none; }
  .ws-content { padding: 14px; }
  .ws-grid { gap: 12px; }
  /* На телефоне карточки в одну колонку — две по 160 px нечитаемы. */
  .ws-grid-kpi, .ws-grid-cards, .ws-grid-tools { grid-template-columns: 1fr; }
  .cmd-overlay { padding: 8vh 10px 10px; }
  .cmd-item-d { display: none; }
}
@media (min-width: 481px) and (max-width: 767px) {
  /* Планшет в портрете и крупные телефоны: две колонки читаются нормально. */
  .ws-grid-tools { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Область прокрутки не должна расширяться содержимым ни на одной ширине. */
.ws-shell, .ws-content, .ws-card, .ws-tool-card { max-width: 100%; }
.ws-content img, .ws-content table { max-width: 100%; }
.ws-break { overflow-wrap: anywhere; word-break: break-word; }

/* ─── Заголовок страницы ─── */
.ws-page-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 6px; }
.ws-page-title { font-size: 28px; font-weight: 800; letter-spacing: -0.01em; margin: 0; }
.ws-page-sub { font-size: 14px; color: var(--ws-text-2, #64748B); margin: 0; }

/* ─── Карточка возможности: кнопка + отдельная звёздочка ─── */
.ws-tool-card-wrap { min-width: 0; }
.ws-tool-card { width: 100%; height: 100%; align-items: flex-start; }
.ws-tool-ic { display: inline-flex; margin-bottom: 2px; color: var(--ws-primary, #2563EB); }
.ws-tool-foot { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: auto; padding-top: 8px; }
/* Звёздочка поверх карточки, но вне её кнопки: вложенная кнопка в кнопку —
   недопустимая разметка, браузеры разбирают её непредсказуемо. */
.ws-tool-star {
  position: absolute; top: 8px; right: 8px; z-index: 2;
  width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center;
  border: 0; background: transparent; cursor: pointer; border-radius: 8px;
  font-size: 15px; line-height: 1; color: var(--ws-text-3, #94A3B8);
}
.ws-tool-star:hover { background: var(--ws-surface-2, #F1F5F9); }
.ws-tool-star.on { color: #F59E0B; }
.ws-tool-star:focus-visible { outline: 2px solid var(--ws-primary, #2563EB); outline-offset: 2px; }

/* ─── Поиск в шапке: кнопка, открывающая палитру ─── */
.ws-search-trigger {
  display: flex; align-items: center; gap: 8px; width: 100%; max-width: 420px;
  padding: 7px 12px; cursor: pointer; text-align: left;
  background: var(--ws-surface-2, #F1F5F9);
  border: 1px solid var(--ws-border, #E5EAF1);
  border-radius: 10px; color: var(--ws-text-3, #94A3B8); font-size: 13px;
}
.ws-search-trigger:hover { border-color: var(--ws-border-2, #D6DEE9); background: #fff; }
.ws-search-trigger:focus-visible { outline: 2px solid var(--ws-primary, #2563EB); outline-offset: 2px; }
.ws-search-ph { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ws-search-kbd {
  font-size: 11px; padding: 2px 6px; border-radius: 5px;
  border: 1px solid var(--ws-border, #E5EAF1); background: #fff; color: var(--ws-text-2, #64748B);
}
@media (max-width: 767px) {
  /* На телефоне подпись и сочетание не помещаются — остаётся значок. */
  .ws-search-ph, .ws-search-kbd { display: none; }
  .ws-search-trigger { width: auto; padding: 8px; justify-content: center; }
  .ws-page-title { font-size: 22px; }
}

/* ─── Расход генераций в шапке ─── */
.ws-usage {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 10px; border-radius: 8px; cursor: pointer;
  border: 1px solid var(--ws-border, #E5EAF1);
  background: var(--ws-surface-2, #F1F5F9);
  color: var(--ws-text-2, #64748B);
  font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums;
}
.ws-usage:hover { border-color: var(--ws-border-2, #D6DEE9); color: var(--ws-text, #0F172A); }
.ws-usage:focus-visible { outline: 2px solid var(--ws-primary, #2563EB); outline-offset: 2px; }

/* ─── Меню «+ Создать» ─── */
.ws-create-menu [data-qc] {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 9px 12px; border: 0; background: transparent; cursor: pointer;
  text-align: left; font-size: 13.5px; color: var(--ws-text, #0F172A);
}
.ws-create-menu [data-qc]:hover,
.ws-create-menu [data-qc]:focus-visible { background: var(--ws-surface-2, #F1F5F9); outline: none; }
.ws-create-menu [data-qc]:focus-visible { box-shadow: inset 2px 0 0 var(--ws-primary, #2563EB); }
.ws-qc-label { font-weight: 500; }
.ws-qc-desc { margin-left: auto; font-size: 11.5px; color: var(--ws-text-3, #94A3B8); white-space: nowrap; }
@media (max-width: 767px) {
  /* На узком экране счётчик и описания действий не помещаются. */
  .ws-usage { display: none; }
  .ws-qc-desc { display: none; }
}

/* ============================================================
   СОВМЕСТИМОСТЬ СО СТАРЫМИ СТИЛЯМИ ВНУТРИ КАБИНЕТА
   ------------------------------------------------------------
   Оболочка задаёт светлый фон, но содержимое разделов — Дашборд,
   Проекты, Позиции, Календарь, Тариф — по-прежнему сверстано на
   переменных общей темы (--text, --card, --border и другие).

   У человека с тёмной темой сайта --text равен почти белому. На светлом
   фоне такой текст не читается вообще: кабинет выглядел бы пустым.
   Проверить это без браузера нельзя, поэтому не полагаемся на удачу и
   переопределяем переменные ВНУТРИ .ws-shell.

   Так старая разметка автоматически получает светлые значения, а публичная
   часть сайта и её тёмная тема не затронуты — правила действуют только
   в границах кабинета.
   ============================================================ */
.ws-shell {
  --bg:      var(--ws-bg);
  --bg2:     var(--ws-surface-2);
  --bg3:     var(--ws-surface-2);
  --card:    var(--ws-surface);
  --card2:   var(--ws-surface-2);
  --border:  var(--ws-border);
  --border2: var(--ws-border-2);
  --bd-ui:   var(--ws-border);
  --text:    var(--ws-text);
  --muted:   var(--ws-text-2);
  --muted2:  var(--ws-text-3);
  --tx-muted: var(--ws-text-2);
  --sb-text-secondary: var(--ws-text-2);
  --sb-border: var(--ws-border);
}

/* Шапка кабинета — часть той же светлой области, но лежит вне .ws-shell
   в потоке страницы, поэтому переменные ей нужно задать отдельно. */
.ws-topbar {
  --bg: var(--ws-bg, #F7F9FC);
  --bg2: var(--ws-surface-2, #F1F5F9);
  --card: var(--ws-surface, #FFFFFF);
  --border: var(--ws-border, #E5EAF1);
  --border2: var(--ws-border-2, #D6DEE9);
  --text: var(--ws-text, #0F172A);
  --muted: var(--ws-text-2, #64748B);
  --muted2: var(--ws-text-3, #94A3B8);
  color: var(--ws-text, #0F172A);
}

/* Пункт меню в старом оформлении подсвечивался градиентом с белым текстом.
   На светлой панели это выглядит чужеродно — оставляем мягкую заливку
   из нового набора. */
.ws-sidebar .app-nav.active,
.ws-sidebar .ws-nav-item.active {
  background: var(--ws-primary-soft);
  color: var(--ws-primary);
}
.ws-sidebar .app-nav:hover { background: var(--ws-surface-2); color: var(--ws-text); }

/* Выпадающие меню шапки тоже светлые: они наследуют переменные от .ws-topbar,
   но у части из них фон задан напрямую. */
.ws-topbar .app-create-menu,
.ws-topbar .notif-dropdown,
.ws-topbar .app-avatar-menu,
.ws-topbar .app-proj-dropdown {
  background: var(--ws-surface, #FFFFFF);
  border: 1px solid var(--ws-border, #E5EAF1);
  box-shadow: var(--ws-shadow-lg, 0 10px 30px rgba(15, 23, 42, 0.10));
  color: var(--ws-text, #0F172A);
}

/* ─── Дашборд ─── */
.ws-kpi { display: flex; flex-direction: column; gap: 6px; min-height: 104px; }
.ws-kpi-label { font-size: 12px; font-weight: 600; color: var(--ws-text-2); }
.ws-kpi-value {
  font-size: 26px; font-weight: 800; letter-spacing: -0.02em; line-height: 1.1;
  font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}
.ws-kpi-suffix { font-size: 14px; font-weight: 600; color: var(--ws-text-3); margin-left: 4px; }
.ws-kpi-note { font-size: 12px; color: var(--ws-text-3); }
/* Пустое состояние показателя не должно выглядеть как значение —
   иначе прочерк читается как «ноль», а это разные вещи. */
.ws-kpi-empty { font-size: 13px; color: var(--ws-text-3); margin-top: 2px; }
.ws-kpi-cta { margin-top: auto; align-self: flex-start; }

.ws-attention-list { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; }
.ws-attention-item {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 12px 14px; border-radius: var(--ws-radius-sm);
  background: var(--ws-surface-2); border-left: 3px solid var(--ws-border-2);
}
.ws-attention-item.crit { background: var(--ws-red-soft);    border-left-color: var(--ws-red); }
.ws-attention-item.warn { background: var(--ws-orange-soft); border-left-color: var(--ws-orange); }
.ws-attention-item.info { background: var(--ws-primary-soft);border-left-color: var(--ws-primary); }
.ws-attention-item > div { flex: 1; min-width: 0; }
.ws-attention-title { font-size: 14px; font-weight: 700; }
.ws-attention-text { font-size: 13px; color: var(--ws-text-2); overflow-wrap: anywhere; }

.ws-buckets { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; margin-top: 10px; }
.ws-bucket { text-align: center; padding: 12px 6px; border-radius: var(--ws-radius-sm); background: var(--ws-surface-2); }
.ws-bucket-v { font-size: 22px; font-weight: 800; font-variant-numeric: tabular-nums; }
.ws-bucket-l { font-size: 11px; font-weight: 600; color: var(--ws-text-2); margin-top: 2px; }

.ws-chip-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.ws-chip-tool {
  display: inline-flex; align-items: center; gap: 6px; max-width: 100%;
  padding: 7px 11px; border-radius: 999px; cursor: pointer;
  background: var(--ws-surface-2); border: 1px solid var(--ws-border);
  font-size: 12.5px; font-weight: 600; color: var(--ws-text);
}
.ws-chip-tool:hover { border-color: var(--ws-border-2); background: #fff; }
.ws-chip-tool:focus-visible { outline: 2px solid var(--ws-primary); outline-offset: 2px; }
.ws-chip-tool .ic { flex: 0 0 14px; width: 14px; height: 14px; color: var(--ws-text-2); }

.ws-list { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.ws-list li { display: flex; gap: 10px; align-items: baseline; font-size: 13px; min-width: 0; }
.ws-list-date { flex: 0 0 auto; font-size: 12px; font-weight: 700; color: var(--ws-primary); font-variant-numeric: tabular-nums; }
.ws-empty-inline { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }

.ws-btn, .ws-btn-sm {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  border-radius: var(--ws-radius-sm); font-weight: 600; white-space: nowrap;
  background: var(--ws-primary); color: #fff; border: 1px solid transparent;
}
.ws-btn { padding: 9px 16px; font-size: 14px; }
.ws-btn-sm { padding: 6px 12px; font-size: 12.5px; }
.ws-btn:hover, .ws-btn-sm:hover { filter: brightness(1.06); }
.ws-btn:focus-visible, .ws-btn-sm:focus-visible { outline: 2px solid var(--ws-primary); outline-offset: 2px; }
.ws-attention-item .ws-btn-sm { background: var(--ws-surface); color: var(--ws-text); border-color: var(--ws-border-2); }

@media (max-width: 767px) {
  /* Четыре колонки распределения на телефоне превращаются в нечитаемые
     столбики по 60 px — оставляем две. */
  .ws-buckets { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ws-kpi-value { font-size: 22px; }
  .ws-attention-item { align-items: flex-start; }
}

/* ─── Карточка проекта ─── */
.ws-proj-card {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  border: 1px solid var(--ws-border); border-radius: var(--ws-radius);
  background: var(--ws-surface); padding: 12px 14px; min-width: 0;
}
.ws-proj-card:hover { border-color: var(--ws-border-2); box-shadow: var(--ws-shadow-sm); }
/* Активный проект помечаем полосой слева, а не рамкой целиком:
   рамка спорит с состоянием наведения и читается как ошибка. */
.ws-proj-card.active { border-left: 3px solid var(--ws-primary); }
.ws-proj-info {
  flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px;
  border: 0; background: transparent; cursor: pointer; text-align: left; padding: 0;
}
.ws-proj-info:focus-visible { outline: 2px solid var(--ws-primary); outline-offset: 3px; border-radius: 6px; }
.ws-proj-info .proj-card-name { font-size: 14px; font-weight: 700; color: var(--ws-text); }
.ws-proj-info .proj-card-meta { font-size: 12.5px; color: var(--ws-text-2); }
.ws-proj-stage {
  flex: 0 0 auto; cursor: pointer; background: transparent;
  border: 1px solid currentColor; border-radius: 999px;
  padding: 4px 10px; font-size: 11.5px; font-weight: 700; white-space: nowrap;
}
.ws-proj-stage:focus-visible { outline: 2px solid var(--ws-primary); outline-offset: 2px; }
@media (max-width: 767px) {
  /* На телефоне действия переносятся под название, иначе строка
     разъезжается и длинный адрес выталкивает кнопки за экран. */
  .ws-proj-card { align-items: flex-start; }
  .ws-proj-info { flex: 1 1 100%; }
}

/* ─── Экран безопасности ─── */
.ws-security-grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); }
/* Опасная зона всегда во всю ширину и последней: необратимое действие
   не должно стоять в одном ряду с обычными настройками. */
.ws-security-grid .ws-danger { grid-column: 1 / -1; border-color: var(--ws-red-soft); }
.ws-btn-danger { background: var(--ws-red); }
@media (max-width: 767px) { .ws-security-grid { grid-template-columns: 1fr; } }

/* ─── Настройки ─── */
.ws-settings-grid { grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); }
.ws-profile-hero { display: flex; gap: 16px; align-items: flex-start; flex-wrap: wrap; }
.ws-profile-meta { flex: 1; min-width: 0; }
.ws-ava {
  width: 64px; height: 64px; flex: 0 0 64px; border-radius: 50%;
  background-size: cover; background-position: center;
  display: inline-flex; align-items: center; justify-content: center;
}
.ws-ava-ini { background: var(--ws-primary-soft); color: var(--ws-primary); font-size: 24px; font-weight: 800; }
.ws-profile-name { font-size: 19px; font-weight: 800; }
.ws-profile-mail { font-size: 13px; color: var(--ws-text-2); margin-top: 2px; }

.ws-label { display: block; font-size: 12px; font-weight: 600; color: var(--ws-text-2); margin: 12px 0 4px; }
.ws-input {
  width: 100%; padding: 9px 12px; font-size: 14px; color: var(--ws-text);
  background: var(--ws-surface); border: 1px solid var(--ws-border);
  border-radius: var(--ws-radius-sm);
}
.ws-input:focus { outline: 2px solid var(--ws-primary); outline-offset: -1px; border-color: var(--ws-primary); }

/* Выбор темы: три равнозначных варианта, активный подсвечен рамкой,
   а не только цветом текста — иначе выбор не читается на светлом фоне. */
.ws-theme-opts { display: grid; gap: 8px; }
.ws-theme-opt {
  display: flex; flex-direction: column; gap: 2px; text-align: left; cursor: pointer;
  padding: 11px 13px; border-radius: var(--ws-radius-sm);
  background: var(--ws-surface); border: 1px solid var(--ws-border);
}
.ws-theme-opt:hover { border-color: var(--ws-border-2); background: var(--ws-surface-2); }
.ws-theme-opt.active { border-color: var(--ws-primary); background: var(--ws-primary-soft); }
.ws-theme-opt:focus-visible { outline: 2px solid var(--ws-primary); outline-offset: 2px; }
.ws-theme-name { font-size: 14px; font-weight: 600; }
.ws-theme-hint { font-size: 12px; color: var(--ws-text-2); }

/* ─── Интеграции ─── */
.ws-section-title { font-size: 15px; font-weight: 700; margin: 20px 0 10px; }
.ws-conn-card { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.ws-conn-head { display: flex; align-items: center; gap: 10px; justify-content: space-between; }
.ws-conn-title { font-size: 15px; font-weight: 700; }
.ws-conn-detail { font-size: 13px; color: var(--ws-text); }
.ws-conn-sync { font-size: 12px; color: var(--ws-text-3); }
.ws-conn-perms { margin: 6px 0 0; padding-left: 18px; font-size: 12.5px; color: var(--ws-text-2); }
.ws-conn-perms li { margin-bottom: 3px; }
.ws-conn-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: auto; padding-top: 10px; }
/* Отключённая кнопка должна выглядеть отключённой: активная на вид кнопка,
   которая ничего не делает, читается как поломка. */
.ws-conn-actions button[disabled] { opacity: 0.5; cursor: not-allowed; }
.ws-btn-ghost { background: var(--ws-surface); color: var(--ws-red); border-color: var(--ws-red-soft); }

@media (max-width: 767px) {
  .ws-settings-grid { grid-template-columns: 1fr; }
  .ws-profile-hero { gap: 12px; }
  .ws-ava { width: 52px; height: 52px; flex-basis: 52px; }
}

/* Пояснение под полем: для read-only полей это единственный способ
   объяснить, почему значение нельзя изменить прямо здесь. */
.ws-field-note { font-size: 12px; color: var(--ws-text-3); margin: 6px 0 0; line-height: 1.45; }
.ws-input[readonly] { background: var(--ws-surface-2); color: var(--ws-text-2); cursor: default; }
.ws-input[readonly]:focus { outline: 2px solid var(--ws-border-2); }

/* ─── Задачи ─── */
.ws-filters { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.ws-filter {
  padding: 6px 12px; border-radius: 999px; cursor: pointer; font-size: 12.5px; font-weight: 600;
  background: var(--ws-surface); border: 1px solid var(--ws-border); color: var(--ws-text-2);
}
.ws-filter:hover { border-color: var(--ws-border-2); color: var(--ws-text); }
.ws-filter.active { background: var(--ws-primary-soft); border-color: var(--ws-primary); color: var(--ws-primary); }
.ws-filter:focus-visible { outline: 2px solid var(--ws-primary); outline-offset: 2px; }

.ws-task-list { display: flex; flex-direction: column; gap: 10px; }
.ws-task { display: flex; align-items: flex-start; gap: 12px; padding: 14px; }
/* Выполненную задачу приглушаем, но не прячем: человек должен видеть,
   что сделано, иначе список выглядит опустевшим без причины. */
.ws-task.done { opacity: 0.62; }
.ws-task.done .ws-task-title { text-decoration: line-through; }
.ws-task-check {
  flex: 0 0 22px; width: 22px; height: 22px; margin-top: 2px; cursor: pointer;
  border-radius: 6px; border: 1.5px solid var(--ws-border-2); background: var(--ws-surface);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; line-height: 1; color: #fff;
}
.ws-task.done .ws-task-check { background: var(--ws-green); border-color: var(--ws-green); }
.ws-task-check:focus-visible { outline: 2px solid var(--ws-primary); outline-offset: 2px; }
.ws-task-body { flex: 1; min-width: 0; }
.ws-task-title { font-size: 14.5px; font-weight: 700; }
.ws-task-desc { font-size: 13px; color: var(--ws-text-2); margin-top: 3px; }
.ws-task-meta { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-top: 8px; font-size: 12px; }
.ws-task-due { color: var(--ws-text-2); font-variant-numeric: tabular-nums; }
.ws-task-due.overdue { color: var(--ws-red); font-weight: 700; }
.ws-task-proj { color: var(--ws-text-3); }
.ws-task-actions { display: flex; gap: 6px; flex-wrap: wrap; flex: 0 0 auto; }
.ws-task-form .ws-form-row { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(min(160px, 100%), 1fr)); }
textarea.ws-input { resize: vertical; min-height: 68px; font-family: inherit; }

/* ─── Отчёты ─── */
.ws-report-card { display: flex; flex-direction: column; gap: 6px; }

@media (max-width: 767px) {
  /* На телефоне действия задачи уходят под текст: в строку они не помещаются
     и выталкивают содержимое за край экрана. */
  .ws-task { flex-wrap: wrap; }
  .ws-task-actions { width: 100%; }
  .ws-task-form .ws-form-row { grid-template-columns: 1fr; }
}

/* ─── Кнопка открытия меню на телефоне ───
   На широком экране меню всегда на виду, кнопка не нужна. На узком боковая
   панель уезжает за край, и без этой кнопки разделы вне нижней панели
   становились недостижимы — попасть в Задачи, Отчёты или Безопасность
   было нельзя вовсе. */
.ws-burger { display: none; }
@media (max-width: 767px) {
  .ws-burger {
    display: inline-flex; align-items: center; justify-content: center;
    width: 38px; height: 38px; flex: 0 0 38px; margin-right: 4px;
    border-radius: var(--ws-radius-sm, 8px); cursor: pointer;
    background: var(--ws-surface-2, #F1F5F9);
    border: 1px solid var(--ws-border, #E5EAF1);
    color: var(--ws-text, #0F172A);
  }
  .ws-burger:hover { background: #fff; border-color: var(--ws-border-2, #D6DEE9); }
  .ws-burger:focus-visible { outline: 2px solid var(--ws-primary, #2563EB); outline-offset: 2px; }
}

/* ═══ ОБОЛОЧКА: логотип, плотность, активный пункт ═══ */
.ws-side-logo {
  display: flex; align-items: center; gap: 9px;
  padding: 16px 16px 10px; min-width: 0;
}
.ws-side-logo img { width: 26px; height: 26px; flex: 0 0 26px; }
.ws-side-logo-text { font-size: 15.5px; font-weight: 800; letter-spacing: -0.01em; color: var(--ws-text); white-space: nowrap; }
.ws-side-logo-text .accent { color: var(--ws-primary); }
.ws-shell[data-collapsed="1"] .ws-side-logo-text { display: none; }
.ws-shell[data-collapsed="1"] .ws-side-logo { justify-content: center; padding: 16px 0 10px; }

/* Активный пункт: мягкая подложка, без градиента — градиент спорит
   с плоскими карточками и читается как элемент другого интерфейса. */
.ws-nav-item.active,
.ws-sidebar .app-nav.active {
  background: var(--ws-primary-soft);
  color: var(--ws-primary);
  font-weight: 600;
}
.ws-nav-item.active .ic { color: var(--ws-primary); }
.ws-nav-item .ic { color: var(--ws-text-3); transition: color .15s; }
.ws-nav-item:hover .ic { color: var(--ws-text-2); }

/* Единый вес иконок: разнобой толщин заметнее, чем разнобой размеров. */
.ws-sidebar .ic { stroke-width: 1.7; }
.ws-nav-item { font-size: 13.5px; padding: 8px 10px; }
.ws-nav-group { padding: 10px 12px 2px; }
.ws-nav-group-title { font-size: 10.5px; letter-spacing: .07em; }

/* ═══ ШАПКА: контролы нормального размера ═══ */
.ws-topbar { padding: 0 20px; gap: 14px; }
.ws-topbar .app-topbar-projswitch {
  display: inline-flex; align-items: center; gap: 8px;
  height: 38px; padding: 0 12px; border-radius: 10px; cursor: pointer;
  background: var(--ws-surface); border: 1px solid var(--ws-border);
  font-size: 13.5px; font-weight: 600; color: var(--ws-text); max-width: 230px;
}
.ws-topbar .app-topbar-projswitch:hover { border-color: var(--ws-border-2); }
.ws-topbar .app-topbar-center { flex: 1; display: flex; justify-content: center; min-width: 0; }
.ws-search-trigger { height: 38px; max-width: 520px; font-size: 13.5px; }
.ws-topbar .app-topbar-create,
.ws-topbar .app-topbar-right > button { height: 38px; }
.ws-topbar .app-topbar-create { padding: 0 16px; font-size: 13.5px; font-weight: 700; border-radius: 10px; }

/* Расход генераций с полосой: цифра без шкалы не даёт почувствовать остаток. */
.ws-usage { flex-direction: column; align-items: flex-start; gap: 3px; height: 38px; padding: 5px 10px; min-width: 92px; }
.ws-usage-bar { width: 100%; height: 4px; border-radius: 3px; background: var(--ws-border); overflow: hidden; }
.ws-usage-fill { height: 100%; background: var(--ws-primary); border-radius: 3px; }
.ws-usage-fill.warn { background: var(--ws-orange); }
.ws-usage-fill.crit { background: var(--ws-red); }

/* ═══ ГЛАВНАЯ: сетка референса ═══ */
.ws-dash-head { margin-bottom: 18px; }
.ws-dash-head .ws-page-title { font-size: 25px; }
.ws-dash-head .ws-page-sub { margin-top: 4px; }

.ws-dash-row {
  display: grid; gap: 16px; margin-bottom: 16px;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
/* Карточки первого ряда держат общую высоту: пустое состояние живёт ВНУТРИ
   карточки, иначе ряд рассыпается на разновысокие обрезки и композиция
   ломается ровно там, где у нового пользователя данных ещё нет. */
.ws-card-tall { min-height: 310px; display: flex; flex-direction: column; }
.ws-dash-row.second .ws-card { min-height: 210px; display: flex; flex-direction: column; }

.ws-card-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
.ws-card-note { font-size: 12px; color: var(--ws-text-3); margin-top: 6px; }

/* Пустое состояние внутри карточки — по центру свободного места. */
.ws-card-empty {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; text-align: center; padding: 18px 8px;
}
.ws-card-empty.sm { padding: 12px 6px; gap: 6px; }
.ws-card-empty .ws-empty-text { max-width: 260px; }
.ws-empty-ok {
  width: 38px; height: 38px; border-radius: 50%; display: inline-flex;
  align-items: center; justify-content: center; font-size: 18px;
  background: var(--ws-green-soft); color: var(--ws-green);
}

.ws-progress { height: 7px; border-radius: 4px; background: var(--ws-surface-2); overflow: hidden; margin-top: 10px; }
.ws-progress-fill { height: 100%; background: var(--ws-primary); border-radius: 4px; transition: width .3s; }

.ws-checklist { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.ws-checklist li { display: flex; align-items: center; gap: 9px; font-size: 13px; min-width: 0; }
.ws-checklist li.done { color: var(--ws-text-2); }
.ws-check-mark {
  width: 18px; height: 18px; flex: 0 0 18px; border-radius: 5px;
  border: 1.5px solid var(--ws-border-2); display: inline-flex;
  align-items: center; justify-content: center; font-size: 11px; color: #fff;
}
.ws-checklist li.done .ws-check-mark { background: var(--ws-green); border-color: var(--ws-green); }
.ws-link-btn {
  margin-left: auto; background: transparent; border: 0; cursor: pointer;
  color: var(--ws-primary); font-size: 12.5px; font-weight: 600; padding: 2px 4px; white-space: nowrap;
}
.ws-link-btn:hover { text-decoration: underline; }
.ws-link-btn:focus-visible { outline: 2px solid var(--ws-primary); outline-offset: 2px; border-radius: 4px; }

.ws-attn-list { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.ws-attn-item {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px;
  border-radius: 9px; background: var(--ws-surface-2); border-left: 3px solid var(--ws-border-2);
}
.ws-attn-item.crit { background: var(--ws-red-soft); border-left-color: var(--ws-red); }
.ws-attn-item.warn { background: var(--ws-orange-soft); border-left-color: var(--ws-orange); }
.ws-attn-item.info { background: var(--ws-primary-soft); border-left-color: var(--ws-primary); }
.ws-attn-body { flex: 1; min-width: 0; }
.ws-attn-title { font-size: 13.5px; font-weight: 700; }
.ws-attn-text { font-size: 12.5px; color: var(--ws-text-2); }

.ws-bars { display: flex; flex-direction: column; gap: 7px; margin-top: 12px; }
.ws-bar-row { display: flex; align-items: center; gap: 9px; font-size: 12px; }
.ws-bar-l { flex: 0 0 52px; color: var(--ws-text-2); }
.ws-bar-track { flex: 1; height: 6px; border-radius: 4px; background: var(--ws-surface-2); overflow: hidden; }
.ws-bar-fill { display: block; height: 100%; background: var(--ws-primary); border-radius: 4px; }
.ws-bar-v { flex: 0 0 34px; text-align: right; color: var(--ws-text-2); font-variant-numeric: tabular-nums; }

.ws-feed { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.ws-feed li { display: flex; align-items: center; gap: 9px; font-size: 13px; min-width: 0; }
.ws-feed-dot { width: 7px; height: 7px; flex: 0 0 7px; border-radius: 50%; background: var(--ws-primary); }
.ws-feed-time { margin-left: auto; font-size: 12px; color: var(--ws-text-3); white-space: nowrap; }

.ws-tasklist { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.ws-tasklist li { display: flex; align-items: center; gap: 9px; font-size: 13px; min-width: 0; }
.ws-dot { width: 8px; height: 8px; flex: 0 0 8px; border-radius: 50%; background: var(--ws-text-3); }
.ws-dot.warn { background: var(--ws-orange); }
.ws-dot.crit { background: var(--ws-red); }
.ws-task-when { margin-left: auto; font-size: 12px; color: var(--ws-text-3); white-space: nowrap; font-variant-numeric: tabular-nums; }
.ws-task-when.overdue { color: var(--ws-red); font-weight: 700; }

/* ═══ Быстрые действия ═══ */
.ws-quick { margin-top: 4px; }
.ws-quick-row { display: grid; gap: 12px; grid-template-columns: repeat(5, minmax(0, 1fr)); }
.ws-quick-card {
  display: flex; align-items: center; gap: 10px; cursor: pointer; text-align: left;
  padding: 13px 14px; border-radius: var(--ws-radius); min-width: 0;
  background: var(--ws-surface); border: 1px solid var(--ws-border); box-shadow: var(--ws-shadow-sm);
}
.ws-quick-card:hover { border-color: var(--ws-primary); box-shadow: var(--ws-shadow); }
.ws-quick-card:focus-visible { outline: 2px solid var(--ws-primary); outline-offset: 2px; }
.ws-quick-ic {
  width: 32px; height: 32px; flex: 0 0 32px; border-radius: 9px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--ws-primary-soft); color: var(--ws-primary);
}
.ws-quick-t { font-size: 13px; font-weight: 600; line-height: 1.3; }

/* ═══ Меню «+ Создать» по референсу ═══ */
.ws-create-menu { min-width: 296px; padding: 6px; border-radius: 13px; }
.ws-create-menu [data-qc] {
  align-items: flex-start; gap: 11px; padding: 10px 11px; border-radius: 9px;
}
.ws-create-menu [data-qc] .ic {
  width: 30px; height: 30px; flex: 0 0 30px; padding: 7px; border-radius: 8px;
  background: var(--ws-primary-soft); color: var(--ws-primary);
}
.ws-create-menu [data-qc] .ws-qc-label { display: block; font-size: 13.5px; font-weight: 600; }
.ws-create-menu [data-qc] .ws-qc-desc {
  display: block; margin: 2px 0 0; font-size: 12px; color: var(--ws-text-3); white-space: normal;
}

@media (max-width: 1180px) {
  .ws-dash-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ws-quick-row { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 767px) {
  .ws-dash-row, .ws-quick-row { grid-template-columns: 1fr; }
  .ws-card-tall { min-height: 0; }
  .ws-dash-head .ws-page-title { font-size: 21px; }
}

/* ═══ Cookie-баннер не должен ломать layout кабинета ═══
   Внутри страницы кабинета баннер оказывался в обычном потоке и занимал
   84 px над оболочкой: шапка отрывалась от бокового меню, а рабочая область
   уезжала вниз. На публичных страницах он задан фиксированным, но там своя
   специфичность — задаём её явно и здесь.
   Держим баннер в правом нижнем углу: там он не перекрывает ни меню, ни
   содержимое, и его видно на любой ширине. */
#page-app .cookie-banner,
.app-page-active .cookie-banner {
  position: fixed; bottom: 20px; right: 20px; left: auto; top: auto;
  z-index: 130; max-width: 380px; width: calc(100% - 40px);
}
#page-app .cookie-banner:not(.show),
.app-page-active .cookie-banner:not(.show) {
  /* Скрытый баннер не должен участвовать в раскладке вообще. */
  display: none;
}
@media (max-width: 767px) {
  /* На телефоне поднимаем над нижней панелью навигации, иначе он её накрывает. */
  #page-app .cookie-banner,
  .app-page-active .cookie-banner { bottom: 84px; right: 12px; left: 12px; width: auto; max-width: none; }
}


/* Смещение шапки задаём на том же уровне специфичности, что и исходное
   правило кабинета (body.app-page-active .app-topbar) — иначе оно
   перебивает наше и шапка растягивается на всю ширину. */
body.app-page-active .app-topbar.ws-topbar {
  --ws-sidebar-w: 220px;
  --ws-sidebar-wc: 68px;
  position: fixed; top: 0; right: 0;
  left: var(--ws-sidebar-w); width: auto;
  transition: left .18s ease;
}
/* Свёрнутое меню: признак стоит на оболочке, которая идёт в разметке ПОСЛЕ
   шапки, поэтому цепляемся за общего предка. */
body.app-page-active:has(.ws-shell[data-collapsed="1"]) .app-topbar.ws-topbar {
  left: var(--ws-sidebar-wc);
}

@media (max-width: 767px) {
  /* На телефоне меню уезжает, шапка занимает всю ширину. */
  body.app-page-active .app-topbar.ws-topbar { left: 0; }
  .ws-content { margin-left: 0; }
}

/* ═══ Позиции: кольцо распределения ═══ */
.ws-donut-wrap { display: flex; align-items: center; gap: 18px; margin-top: 14px; flex-wrap: wrap; }
.ws-donut {
  width: 128px; height: 128px; flex: 0 0 128px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; position: relative;
}
/* Отверстие вырезаем белым кругом поверх градиента: маска работает не везде,
   а фон карточки здесь всегда белый. */
.ws-donut-hole {
  width: 88px; height: 88px; border-radius: 50%; background: var(--ws-surface);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.ws-donut-v { font-size: 24px; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; }
.ws-donut-l { font-size: 11px; color: var(--ws-text-3); margin-top: 2px; }
.ws-legend { list-style: none; margin: 0; padding: 0; flex: 1; min-width: 150px; display: flex; flex-direction: column; gap: 8px; }
.ws-legend li { display: flex; align-items: center; gap: 8px; font-size: 12.5px; }
.ws-legend-dot { width: 9px; height: 9px; flex: 0 0 9px; border-radius: 3px; }
.ws-legend-l { flex: 1; color: var(--ws-text-2); }
.ws-legend-v { font-weight: 700; font-variant-numeric: tabular-nums; }
.ws-legend-p { width: 38px; text-align: right; color: var(--ws-text-3); font-variant-numeric: tabular-nums; }

/* ═══ Активность: иконка вместо точки ═══ */
.ws-feed-ic {
  width: 26px; height: 26px; flex: 0 0 26px; border-radius: 7px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--ws-surface-2); color: var(--ws-text-2);
}

/* ═══ Недавно использовали: плитка ═══ */
.ws-tile-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; margin-top: 12px; }
.ws-tile {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 10px 6px; border-radius: 10px; cursor: pointer; min-width: 0;
  background: var(--ws-surface); border: 1px solid var(--ws-border);
}
.ws-tile:hover { border-color: var(--ws-primary); background: var(--ws-primary-soft); }
.ws-tile:focus-visible { outline: 2px solid var(--ws-primary); outline-offset: 2px; }
.ws-tile-ic {
  width: 30px; height: 30px; border-radius: 8px; display: inline-flex;
  align-items: center; justify-content: center;
  background: var(--ws-primary-soft); color: var(--ws-primary);
}
.ws-tile-t { font-size: 11px; font-weight: 600; text-align: center; line-height: 1.25; }

/* ═══ Задачи: рамка статуса вместо точки ═══ */
.ws-task-box {
  width: 16px; height: 16px; flex: 0 0 16px; border-radius: 5px;
  border: 1.6px solid var(--ws-border-2); background: var(--ws-surface);
}
.ws-task-box.progress { border-color: var(--ws-primary); background: var(--ws-primary-soft); }
.ws-task-box.warn { border-color: var(--ws-orange); }
.ws-task-box.crit { border-color: var(--ws-red); }
.ws-task-when.today { color: var(--ws-orange); font-weight: 700; }

/* ═══ Кнопка сворачивания внизу меню ═══ */
.ws-collapse-btn {
  display: flex; align-items: center; gap: 10px; width: 100%;
  margin-top: 6px; padding: 8px 10px; border: 0; cursor: pointer;
  border-radius: var(--ws-radius-sm); background: transparent;
  color: var(--ws-text-3); font-size: 13px; font-weight: 500; text-align: left;
}
.ws-collapse-btn:hover { background: var(--ws-surface-2); color: var(--ws-text-2); }
.ws-collapse-btn:focus-visible { outline: 2px solid var(--ws-primary); outline-offset: 2px; }
.ws-collapse-btn .collapse-ic-out { display: none; }
.ws-shell[data-collapsed="1"] .ws-collapse-btn { justify-content: center; padding: 10px; }
.ws-shell[data-collapsed="1"] .ws-collapse-btn .collapse-ic-in { display: none; }
.ws-shell[data-collapsed="1"] .ws-collapse-btn .collapse-ic-out { display: inline; }

/* ═══ Пропорции под 1536×1024 ═══ */
@media (min-width: 1400px) {
  .ws-card-tall { min-height: 344px; }
  .ws-dash-row.second .ws-card { min-height: 230px; }
}
@media (max-width: 1180px) {
  .ws-tile-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ═══ Переключатель проекта: подпись и значение ═══ */
body.app-page-active .app-topbar .ws-proj-btn {
  height: 44px; padding: 0 12px; align-items: center; gap: 10px;
}
.ws-proj-col { display: flex; flex-direction: column; align-items: flex-start; gap: 1px; min-width: 0; }
.ws-proj-cap { font-size: 10.5px; font-weight: 600; color: var(--ws-text-3); line-height: 1.1; letter-spacing: .02em; }
.ws-proj-name {
  font-size: 13.5px; font-weight: 700; color: var(--ws-text); line-height: 1.2;
  max-width: 170px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ═══ Использование: подпись, значение, полоса ═══ */
.ws-usage {
  flex-direction: column; align-items: flex-start; justify-content: center;
  gap: 2px; height: 44px; padding: 5px 12px; min-width: 118px;
}
.ws-usage-cap { font-size: 10.5px; font-weight: 600; color: var(--ws-text-3); line-height: 1.1; }
.ws-usage-val { font-size: 13px; font-weight: 700; color: var(--ws-text); line-height: 1.2; font-variant-numeric: tabular-nums; }
.ws-usage-bar { width: 100%; height: 4px; margin-top: 2px; }

/* Контролы шапки одной высоты: разнобой в 6 px заметнее, чем кажется. */
body.app-page-active .app-topbar .app-topbar-create,
body.app-page-active .app-topbar .app-topbar-right > button { height: 44px; }
body.app-page-active .app-topbar { --ws-topbar-h: 66px; height: 66px; }

/* ═══ Меню «+ Создать»: иконка слева, текст колонкой ═══
   Название и описание были рядом в строку и читались как две колонки
   таблицы — глаз искал между ними связь, которой нет. */
.ws-create-menu [data-qc] { display: flex; align-items: flex-start; gap: 11px; }
.ws-create-menu [data-qc] .ws-qc-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ws-create-menu [data-qc] .ws-qc-label { margin: 0; font-size: 13.5px; font-weight: 600; white-space: normal; }
.ws-create-menu [data-qc] .ws-qc-desc {
  margin: 0; margin-left: 0; font-size: 12px; color: var(--ws-text-3);
  white-space: normal; max-width: none; text-align: left;
}

/* ═══ Плотность низа Главной ═══ */
.ws-dash-row.second { margin-bottom: 8px; }
.ws-quick { margin-top: 0; }

/* ============================================================
   ТЁМНАЯ ТЕМА WORKSPACE
   ------------------------------------------------------------
   Тёмными становились только те места, где цвет брался из общей темы
   сайта: шапка и меню профиля. Всё остальное в кабинете читает набор
   --ws-*, а он был задан светлыми значениями безусловно — отсюда белые
   боковое меню и карточки на тёмном фоне.

   Поэтому переключаем НАБОР ТОКЕНОВ, а не отдельные элементы. Ни одна
   страница кабинета не знает о теме: она берёт --ws-surface и получает
   нужное значение. Добавление нового экрана не требует правок здесь.

   Переключатель — html[data-theme="dark"], тот же, что уже ставит
   applyAppTheme(): режим «как в системе» вычисляется там и приводится
   к тому же атрибуту, поэтому отдельной ветки для него не нужно.
   ============================================================ */
html[data-theme="dark"] .ws-shell,
html[data-theme="dark"] .ws-topbar,
html[data-theme="dark"] .cmd-box {
  --ws-bg:        #0F1420;
  --ws-surface:   #171F2E;
  --ws-surface-2: #1D2637;
  --ws-border:    #2A3548;
  --ws-border-2:  #38455C;

  --ws-text:      #F3F6FC;
  --ws-text-2:    #9DA9BC;
  --ws-text-3:    #71809A;

  /* Брендовый фиолетовый сохраняем, подложку делаем заметнее: на тёмном
     фоне прозрачность 10% почти не читается. */
  --ws-primary:      #8B7BF0;
  --ws-primary-soft: rgba(139, 123, 240, 0.18);

  /* Смысловые цвета осветлены: исходные тона рассчитаны на белый фон и
     на тёмном теряют контраст — красный сливается с фоном, зелёный
     выглядит грязным. */
  --ws-green:  #4ADE80;  --ws-green-soft:  rgba(74, 222, 128, 0.16);
  --ws-orange: #FBA94C;  --ws-orange-soft: rgba(251, 169, 76, 0.16);
  --ws-red:    #F87171;  --ws-red-soft:    rgba(248, 113, 113, 0.16);
  --ws-purple: #A78BFA;  --ws-purple-soft: rgba(167, 139, 250, 0.16);
  --ws-cyan:   #38BDF8;  --ws-cyan-soft:   rgba(56, 189, 248, 0.16);

  /* Тени на тёмном не работают как разделитель — глубину даёт граница.
     Оставляем их почти незаметными, чтобы не появлялось грязных ореолов. */
  --ws-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.30);
  --ws-shadow:    0 2px 6px rgba(0, 0, 0, 0.35);
  --ws-shadow-lg: 0 12px 34px rgba(0, 0, 0, 0.50);
}

/* Переменные общей темы внутри кабинета: старая разметка разделов читает
   --text, --card, --border. Без этого Проекты, Задачи и Настройки
   остались бы светлыми островками на тёмном фоне. */
html[data-theme="dark"] .ws-shell,
html[data-theme="dark"] .ws-topbar {
  --bg:      var(--ws-bg);
  --bg2:     var(--ws-surface-2);
  --bg3:     var(--ws-surface-2);
  --card:    var(--ws-surface);
  --card2:   var(--ws-surface-2);
  --border:  var(--ws-border);
  --border2: var(--ws-border-2);
  --bd-ui:   var(--ws-border);
  --text:    var(--ws-text);
  --muted:   var(--ws-text-2);
  --muted2:  var(--ws-text-3);
  --tx-muted: var(--ws-text-2);
  --sb-text-secondary: var(--ws-text-2);
  --sb-border: var(--ws-border);
}

/* Фон рабочей области и цвет текста задаём явно: у .ws-shell фон был
   прописан значением, а не токеном. */
html[data-theme="dark"] .ws-shell { background: var(--ws-bg); color: var(--ws-text); }
html[data-theme="dark"] .ws-sidebar { background: var(--ws-surface); border-right-color: var(--ws-border); }
html[data-theme="dark"] body.app-page-active .app-topbar.ws-topbar,
html[data-theme="dark"] .ws-topbar {
  background: rgba(23, 31, 46, 0.92);
  border-bottom-color: var(--ws-border);
  color: var(--ws-text);
}

/* Поля ввода: светло-серая заливка на тёмном читается как выключенное
   поле, поэтому фон берём из вложенной поверхности. */
html[data-theme="dark"] .ws-input,
html[data-theme="dark"] .ws-search-trigger,
html[data-theme="dark"] .cmd-input,
html[data-theme="dark"] .ws-shell input:not([type=checkbox]):not([type=radio]),
html[data-theme="dark"] .ws-shell textarea,
html[data-theme="dark"] .ws-shell select {
  background: var(--ws-surface-2);
  border-color: var(--ws-border);
  color: var(--ws-text);
}
html[data-theme="dark"] .ws-shell ::placeholder { color: var(--ws-text-3); }
html[data-theme="dark"] .ws-input[readonly] { background: var(--ws-bg); color: var(--ws-text-2); }

/* Выпадающие меню шапки и командная палитра. */
html[data-theme="dark"] .ws-topbar .app-create-menu,
html[data-theme="dark"] .ws-topbar .notif-dropdown,
html[data-theme="dark"] .ws-topbar .app-avatar-menu,
html[data-theme="dark"] .ws-topbar .app-proj-dropdown,
html[data-theme="dark"] .cmd-box {
  background: var(--ws-surface);
  border-color: var(--ws-border);
  color: var(--ws-text);
}
html[data-theme="dark"] .cmd-head,
html[data-theme="dark"] .cmd-foot { border-color: var(--ws-border); }
html[data-theme="dark"] .cmd-item { color: var(--ws-text); }
html[data-theme="dark"] .cmd-item:hover,
html[data-theme="dark"] .cmd-item.active { background: var(--ws-surface-2); }
html[data-theme="dark"] .cmd-kbd,
html[data-theme="dark"] .cmd-foot kbd,
html[data-theme="dark"] .ws-search-kbd {
  background: var(--ws-surface-2); border-color: var(--ws-border); color: var(--ws-text-2);
}

/* Вторичные и «призрачные» кнопки: белый фон делал из них световые пятна. */
html[data-theme="dark"] .ws-btn-sm,
html[data-theme="dark"] .ws-chip-tool,
html[data-theme="dark"] .ws-tile,
html[data-theme="dark"] .ws-filter,
html[data-theme="dark"] .ws-quick-card,
html[data-theme="dark"] .ws-theme-opt,
html[data-theme="dark"] .ws-proj-btn,
html[data-theme="dark"] .ws-usage,
html[data-theme="dark"] .ws-burger {
  background: var(--ws-surface-2);
  border-color: var(--ws-border);
  color: var(--ws-text);
}
html[data-theme="dark"] .ws-chip-tool:hover,
html[data-theme="dark"] .ws-tile:hover,
html[data-theme="dark"] .ws-quick-card:hover,
html[data-theme="dark"] .ws-theme-opt:hover { background: var(--ws-bg); border-color: var(--ws-border-2); }
html[data-theme="dark"] .ws-btn-ghost { background: var(--ws-surface-2); color: var(--ws-red); }
html[data-theme="dark"] .ws-conn-actions button[disabled] { background: var(--ws-surface-2); }

/* Отверстие кольца — цвет карточки, иначе на тёмном остаётся белый круг. */
html[data-theme="dark"] .ws-donut-hole { background: var(--ws-surface); }

/* Кольцо загрузки, полосы и разделители. */
html[data-theme="dark"] .ws-skeleton {
  background: linear-gradient(90deg, var(--ws-surface-2) 25%, #243049 37%, var(--ws-surface-2) 63%);
  background-size: 400% 100%;
}
html[data-theme="dark"] .ws-progress,
html[data-theme="dark"] .ws-bar-track,
html[data-theme="dark"] .ws-usage-bar { background: var(--ws-bg); }

/* Пустые состояния и таблицы. */
html[data-theme="dark"] .ws-empty { background: var(--ws-surface); border-color: var(--ws-border-2); }
html[data-theme="dark"] .ws-shell table { color: var(--ws-text); }
html[data-theme="dark"] .ws-shell th,
html[data-theme="dark"] .ws-shell td { border-color: var(--ws-border); }

/* Затемнение под выдвижной панелью и модальными окнами. */
html[data-theme="dark"] .cmd-overlay { background: rgba(0, 0, 0, 0.55); }

/* Полосы прокрутки: светлая полоса на тёмном фоне бросается в глаза. */
html[data-theme="dark"] .ws-shell *::-webkit-scrollbar { width: 10px; height: 10px; }
html[data-theme="dark"] .ws-shell *::-webkit-scrollbar-track { background: var(--ws-bg); }
html[data-theme="dark"] .ws-shell *::-webkit-scrollbar-thumb {
  background: var(--ws-border); border-radius: 6px; border: 2px solid var(--ws-bg);
}
html[data-theme="dark"] .ws-shell { scrollbar-color: var(--ws-border) var(--ws-bg); }

/* ═══ Аналитика ═══ */
.ws-ana-empty { padding: 40px 24px; }
.ws-svc-card { display: flex; flex-direction: column; gap: 6px; }

/* График рисуем ТОЛЬКО когда есть данные: пустой график с осями 0/1
   создаёт впечатление работающей аналитики без посещений. */
.ws-ana-chart {
  display: flex; align-items: flex-end; gap: 4px;
  height: 180px; margin-top: 14px; padding: 8px 0;
  border-bottom: 1px solid var(--ws-border);
}
.ws-ana-bar {
  flex: 1; min-width: 0; border-radius: 4px 4px 0 0;
  background: linear-gradient(180deg, var(--ws-primary), var(--ws-primary-soft));
}
.ws-ana-axis {
  display: flex; justify-content: space-between;
  margin-top: 6px; font-size: 11.5px; color: var(--ws-text-3);
}

/* ============================================================
   МОБИЛЬНАЯ И ПЛАНШЕТНАЯ АДАПТАЦИЯ КАБИНЕТА
   ============================================================ */

/* Лестница наложения. Раньше значения ставились по месту, и панели
   перекрывали друг друга непредсказуемо: уведомления оказывались под
   меню, меню профиля — поверх выдвижной панели. Порядок здесь один
   и читается сверху вниз. */
.ws-sidebar        { z-index: 120; }
.ws-side-backdrop,
#page-app .app-side-backdrop { z-index: 110; }
body.app-page-active .app-topbar.ws-topbar { z-index: 100; }
.ws-topbar .app-proj-dropdown,
.ws-topbar .app-create-menu,
.ws-topbar .notif-dropdown,
.ws-topbar .app-avatar-menu { z-index: 130; }
.cmd-overlay       { z-index: 200; }
#page-app .cookie-banner,
.app-page-active .cookie-banner { z-index: 90; }

/* Иконка поиска — только на узком экране: там полноразмерное поле
   съедает всю шапку и прижимает кнопки друг к другу. */
.ws-search-icon { display: none; }

@media (max-width: 767px) {
  /* ── Шапка ──
     Слева бургер и компактный переключатель проекта, справа поиск,
     уведомления и профиль. Поле поиска прячется в иконку: в один ряд
     с ним не помещается ничего. */
  body.app-page-active .app-topbar.ws-topbar {
    height: 56px; padding: 0 10px; gap: 6px;
    padding-top: env(safe-area-inset-top, 0px);
    height: calc(56px + env(safe-area-inset-top, 0px));
  }
  .ws-topbar .app-topbar-center { display: none; }
  .ws-search-icon {
    display: inline-flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; flex: 0 0 40px; cursor: pointer;
    border-radius: 10px; background: transparent; border: 0; color: var(--ws-text-2);
  }
  .ws-search-icon:hover { background: var(--ws-surface-2); color: var(--ws-text); }
  .ws-search-icon:focus-visible { outline: 2px solid var(--ws-primary); outline-offset: 2px; }

  /* Переключатель проекта сжимается, но остаётся доступным: без него
     человек на телефоне не понимает, с каким сайтом работает. */
  body.app-page-active .app-topbar .ws-proj-btn {
    height: 40px; padding: 0 8px; max-width: 150px; flex: 0 1 auto; min-width: 0;
  }
  .ws-proj-cap { display: none; }
  .ws-proj-name { font-size: 13px; max-width: 108px; }

  /* Размер нажимаемой области не меньше 40 px и промежутки между
     кнопками: слипшиеся квадраты на телефоне промахиваются пальцем. */
  body.app-page-active .app-topbar .app-topbar-right { display: flex; align-items: center; gap: 4px; }
  body.app-page-active .app-topbar .app-topbar-right > *,
  .ws-burger { min-width: 40px; min-height: 40px; }
  .ws-burger { width: 40px; height: 40px; flex: 0 0 40px; margin-right: 2px; }

  /* Лишние на телефоне элементы шапки. Функции доступны: расход —
     в разделе «Тариф», создание — кнопкой на Главной и в меню. */
  .ws-usage, .ws-topbar .app-topbar-create { display: none; }

  /* ── Выдвижное меню ── */
  .ws-sidebar { width: min(300px, 86vw); box-shadow: var(--ws-shadow-lg); }
  #page-app .app-side-backdrop {
    position: fixed; inset: 0; background: rgba(15, 23, 42, 0.45);
    opacity: 0; pointer-events: none; transition: opacity .2s;
  }
  #page-app .app-side-backdrop.open { opacity: 1; pointer-events: auto; }

  /* ── Cookie-баннер ──
     Внизу и компактно. Наверху он закрывал шапку и первый экран, а в
     потоке — сдвигал всю рабочую область вниз. */
  #page-app .cookie-banner,
  .app-page-active .cookie-banner {
    position: fixed; left: 10px; right: 10px; top: auto;
    bottom: calc(72px + env(safe-area-inset-bottom, 0px));
    width: auto; max-width: none; padding: 12px 14px; border-radius: 12px;
    font-size: 13px; line-height: 1.4;
  }

  /* ── Содержимое ── */
  .ws-content {
    padding: 14px 12px;
    padding-top: calc(56px + env(safe-area-inset-top, 0px) + 14px);
    /* Место под нижнюю панель навигации: без него последняя карточка
       уходит под неё и до кнопок в ней не дотянуться. */
    padding-bottom: calc(84px + env(safe-area-inset-bottom, 0px));
  }
  .ws-dash-row, .ws-quick-row, .ws-grid-kpi, .ws-grid-cards, .ws-grid-tools,
  .ws-settings-grid, .ws-security-grid, .ws-conn-grid { grid-template-columns: 1fr; }
  .ws-dash-row { gap: 12px; margin-bottom: 12px; }
  .ws-card { padding: 14px; }
  .ws-card-tall, .ws-dash-row.second .ws-card { min-height: 0; }

  /* Главное действие карточки — во всю ширину: кнопка в углу узкой
     карточки промахивается пальцем и теряется. */
  .ws-card-empty .ws-btn,
  .ws-empty .ws-btn,
  .ws-ana-empty .ws-btn { width: 100%; }

  /* Пункт «требует внимания»: кнопка под текстом, а не рядом — в строку
     они налезали друг на друга. */
  .ws-attn-item { flex-direction: column; align-items: stretch; gap: 8px; }
  .ws-attn-item .ws-btn-sm { width: 100%; }

  /* Кольцо позиций и легенда — колонкой. */
  .ws-donut-wrap { flex-direction: column; align-items: center; gap: 12px; }
  .ws-legend { width: 100%; }

  /* Плитка недавних: три в ряд вместо четырёх. */
  .ws-tile-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  /* Заголовки и подписи не должны обрезаться. */
  .ws-page-title { font-size: 21px; line-height: 1.25; }
  .ws-page-head { flex-direction: column; align-items: flex-start; gap: 10px; }
  .ws-card-title, .ws-conn-title, .ws-task-title { overflow-wrap: anywhere; }

  /* Фильтры и чипы прокручиваются, а не ломают строку. */
  .ws-filters { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 4px; scrollbar-width: none; }
  .ws-filters::-webkit-scrollbar { display: none; }
  .ws-filter { flex: 0 0 auto; }

  /* Выпадающие меню шапки не должны выходить за экран. */
  .ws-topbar .app-create-menu,
  .ws-topbar .notif-dropdown,
  .ws-topbar .app-avatar-menu,
  .ws-topbar .app-proj-dropdown {
    position: fixed; left: 10px; right: 10px; top: calc(60px + env(safe-area-inset-top, 0px));
    width: auto; min-width: 0; max-width: none; max-height: 70vh; overflow-y: auto;
  }

  /* Формы: поля во всю ширину, иначе на 320 они обрезаются. */
  .ws-input, .ws-task-form .ws-input { max-width: none; }
  .ws-form-row { grid-template-columns: 1fr; }

  /* AI Workflow: карточки генераторов в одну колонку, чипы шаблонов
     прокручиваются. */
  .ws-shell .wf-tools { grid-template-columns: 1fr; }
  .ws-shell .wf-templates-bar { flex-wrap: nowrap; overflow-x: auto; }
  .ws-shell .wf-wrap { padding-left: 0; padding-right: 0; }
}

@media (max-width: 380px) {
  /* 320–375: переключатель проекта сжимается сильнее, плитка в две колонки. */
  body.app-page-active .app-topbar .ws-proj-btn { max-width: 112px; }
  .ws-proj-name { max-width: 74px; }
  .ws-tile-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ws-content { padding-left: 10px; padding-right: 10px; }
}

/* ── Планшет: 769–1199 ──
   Не «уменьшенный десктоп» и не «растянутый телефон»: меню остаётся
   выдвижным, но сетка уже двухколоночная. */
/* Планшет начинается с 768: это ширина iPad в портрете, и она должна
   вести себя как планшет, а не как «широкий телефон». Мобильные правила
   ниже обрезаны до 767, чтобы диапазоны не пересекались — раньше на 768
   действовали оба набора, и меню оставалось раскрытым поверх содержимого. */
@media (min-width: 768px) and (max-width: 1199px) {
  .ws-shell { --ws-off: 0px; }
  .ws-sidebar {
    width: min(300px, 60vw); transform: translateX(-100%); transition: transform .22s ease;
    box-shadow: var(--ws-shadow-lg);
  }
  .ws-sidebar.open { transform: none; }
  body.app-page-active .app-topbar.ws-topbar { left: 0; height: 60px; }
  .ws-burger { display: inline-flex; }
  .ws-content { margin-left: 0; padding: 18px; padding-top: 78px; }
  .ws-dash-row, .ws-grid-cards, .ws-grid-tools, .ws-settings-grid, .ws-security-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .ws-quick-row { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* Карточки одной строки одной высоты: разнобой на планшете заметнее,
     чем на телефоне, где всё в колонку. */
  .ws-card-tall { min-height: 300px; }
  .ws-dash-row.second .ws-card { min-height: 200px; }
  .ws-search-trigger { max-width: 320px; }
  #page-app .cookie-banner,
  .app-page-active .cookie-banner { left: auto; right: 18px; bottom: 18px; width: min(420px, 60vw); }
}

/* ============================================================
   АДАПТАЦИЯ КАБИНЕТА: ТЕЛЕФОН И ПЛАНШЕТ
   Настольная раскладка не меняется — все правила ниже живут
   в медиазапросах и начинаются от 1100 px и уже.
   ============================================================ */

/* ─── Шапка: убираем лишнее по мере сужения ───
   Порядок отказа: сначала подписи, потом целые контролы. Так до последнего
   остаются те действия, ради которых человек открывает кабинет с телефона:
   меню, проект, уведомления, профиль. */
@media (max-width: 1100px) {
  /* Поиск сжимается до значка: обрезанная надпись «Поиск ин…» хуже,
     чем честный значок — она выглядит поломкой, а не сокращением. */
  body.app-page-active .app-topbar .ws-search-trigger {
    width: 40px; max-width: 40px; padding: 0; justify-content: center;
  }
  body.app-page-active .app-topbar .ws-search-ph,
  body.app-page-active .app-topbar .ws-search-kbd { display: none; }
}
@media (max-width: 980px) {
  /* Расход генераций — справочная величина, на узкой шапке она вытесняет
     действия. Остаётся в разделе «Тариф», куда и ведёт. */
  body.app-page-active .app-topbar .ws-usage { display: none; }
  /* «Создать» сжимается до значка с плюсом. */
  body.app-page-active .app-topbar .app-topbar-create { padding: 0 12px; }
  body.app-page-active .app-topbar .app-topbar-create .ws-create-label,
  body.app-page-active .app-topbar .app-topbar-create .ws-create-caret { display: none; }
}
@media (max-width: 767px) {
  body.app-page-active .app-topbar.ws-topbar {
    height: 56px; padding: 0 10px; gap: 8px;
    /* Вырез и «чёлка»: без этого шапка уезжает под системную полосу. */
    padding-top: env(safe-area-inset-top, 0px);
    height: calc(56px + env(safe-area-inset-top, 0px));
  }
  body.app-page-active .app-topbar .app-topbar-center { display: none; }
  body.app-page-active .app-topbar .app-topbar-create { display: none; }
  body.app-page-active .app-topbar .ws-proj-btn { height: 38px; max-width: 150px; padding: 0 10px; }
  body.app-page-active .app-topbar .ws-proj-cap { display: none; }
  body.app-page-active .app-topbar .ws-proj-name { font-size: 13px; }
  body.app-page-active .app-topbar .app-topbar-right > * { margin-left: 0; }
  /* Пальцу нужно не меньше 40 px: кнопки в 30 px промахиваются. */
  body.app-page-active .app-topbar button { min-width: 40px; min-height: 40px; }
  .ws-burger { width: 40px; height: 40px; flex-basis: 40px; }
}

/* ─── Рабочая область ─── */
@media (max-width: 767px) {
  .ws-content {
    padding: 14px 14px 90px;
    /* Пустая полоса под шапкой была почти в экран высотой: отступ считался
       от настольной высоты шапки плюс 24 px. Считаем от фактической. */
    padding-top: calc(56px + env(safe-area-inset-top, 0px) + 14px);
  }
  .ws-dash-head { margin-bottom: 14px; }
  .ws-dash-row { gap: 12px; margin-bottom: 12px; }
  .ws-card { padding: 14px; }
  .ws-card-tall, .ws-dash-row.second .ws-card { min-height: 0; }
  /* Кнопка во всю ширину: на узком экране она иначе теряется в углу. */
  .ws-card-empty .ws-btn, .ws-empty .ws-btn { width: 100%; }
  .ws-quick-row { grid-template-columns: 1fr; }
  .ws-quick-card { padding: 12px 14px; }
  .ws-attn-item { flex-wrap: wrap; }
  .ws-attn-item .ws-btn-sm { width: 100%; }
  /* Кольцо и легенда друг под другом: рядом они сжимаются до нечитаемого. */
  .ws-donut-wrap { flex-direction: column; align-items: flex-start; gap: 12px; }
  .ws-legend { width: 100%; }
  .ws-page-title { font-size: 21px; }
  .ws-section-title { margin: 16px 0 8px; }
}

/* ─── Планшет: две колонки, но без настольной плотности ─── */
@media (min-width: 768px) and (max-width: 1100px) {
  .ws-content { padding: 18px; padding-top: calc(var(--ws-topbar-h) + 18px); }
  .ws-dash-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Третья карточка ряда занимает всю ширину — иначе она вдвое уже соседей
     и ряд выглядит обрубленным. */
  .ws-dash-row > :nth-child(3) { grid-column: 1 / -1; }
  .ws-quick-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ws-grid-tools, .ws-grid-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ws-security-grid, .ws-settings-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ws-tile-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* ─── Выдвижное меню и затемнение ───
   Порядок слоёв задаём явно, одним местом: затемнение под меню, меню под
   всплывающими панелями шапки. Раньше значения стояли вразнобой по файлам,
   и панели наползали друг на друга непредсказуемо. */
@media (max-width: 767px) {
  .ws-sidebar { z-index: 1200; width: min(300px, 86vw); }
  #page-app .app-side-backdrop,
  .app-side-backdrop { z-index: 1150; }
  body.app-page-active .app-topbar.ws-topbar { z-index: 1100; }
  .ws-topbar .app-create-menu,
  .ws-topbar .notif-dropdown,
  .ws-topbar .app-avatar-menu,
  .ws-topbar .app-proj-dropdown { z-index: 1300; }
  .cmd-overlay { z-index: 1400; }
  /* Выпадающие панели шапки на телефоне занимают почти всю ширину:
     панель в 320 px на экране 360 px прижимается к краю и обрезается. */
  .ws-topbar .notif-dropdown,
  .ws-topbar .app-avatar-menu,
  .ws-topbar .app-proj-dropdown {
    position: fixed; left: 8px; right: 8px; width: auto; max-width: none;
    top: calc(56px + env(safe-area-inset-top, 0px) + 6px);
    max-height: calc(100dvh - 56px - 120px); overflow-y: auto;
  }
}

/* ─── Нижняя панель навигации ─── */
@media (max-width: 767px) {
  .ws-bottomnav, .ds-bottomnav {
    padding-bottom: env(safe-area-inset-bottom, 0px);
    z-index: 1000;
  }
}

/* ─── Cookie-баннер ───
   На телефоне он перекрывал кнопки карточек и нижнюю навигацию. Делаем
   компактной полосой над навигацией и добавляем содержимому запас снизу,
   пока баннер виден, — иначе последняя карточка остаётся под ним. */
@media (max-width: 767px) {
  #page-app .cookie-banner,
  .app-page-active .cookie-banner {
    left: 8px; right: 8px; bottom: calc(64px + env(safe-area-inset-bottom, 0px));
    width: auto; max-width: none; z-index: 1050;
    padding: 12px 14px; font-size: 12.5px; border-radius: 12px;
  }
  body.cookie-open .ws-content { padding-bottom: 190px; }
}
@media (min-width: 768px) and (max-width: 1100px) {
  #page-app .cookie-banner,
  .app-page-active .cookie-banner { max-width: 420px; bottom: 16px; right: 16px; left: auto; }
  body.cookie-open .ws-content { padding-bottom: 120px; }
}

/* ─── AI Workflow ─── */
@media (max-width: 767px) {
  .ws-content .wf-wrap { padding: 0; }
  .ws-content .wf-tools { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .ws-content .wf-tool { padding: 10px; }
  /* Полоса шаблонов прокручивается вбок вместо того, чтобы растягивать
     страницу: иначе появляется горизонтальная прокрутка всего экрана. */
  .ws-content .wf-templates-bar { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 6px; }
  .ws-content .wf-templates-bar > * { flex: 0 0 auto; }
  .ws-content .wf-presets { flex-wrap: wrap; }
  .ws-content textarea { min-height: 96px; }
}
@media (min-width: 768px) and (max-width: 1100px) {
  .ws-content .wf-tools { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ─── Формы и таблицы на узком экране ─── */
@media (max-width: 767px) {
  /* Ширину полей задаём тем же селектором, что и в разделах, где стоит
     inline max-width: перебивать чужой стиль повышением важности значит
     оставить конфликт, который всплывёт в следующей правке. */
  .ws-content [style*="max-width"].ws-input,
  .ws-content .ws-input,
  .ws-content select,
  .ws-content textarea { max-width: 100%; }
  .ws-task-form .ws-form-row { grid-template-columns: 1fr; }
  .ws-filters { overflow-x: auto; flex-wrap: nowrap; padding-bottom: 4px; }
  .ws-filters > * { flex: 0 0 auto; }
  .ws-content table { display: block; overflow-x: auto; }
}


/* ─── Дубль заголовка раздела на телефоне ───
   Отдельная полоса .app-mobile-bar с названием раздела шла ПОД шапкой
   в обычном потоке и занимала 48 px. Вместе с настольным отступом
   рабочей области это давало пустую полосу почти в треть экрана над
   приветствием, а само название дублировало то, что и так подсвечено
   в меню и написано заголовком страницы.
   Скрываем полосу; отступ считаем только от фактической высоты шапки. */
@media (max-width: 767px) {
  #page-app .app-mobile-bar { display: none; }
  .app-shell.ws-shell { padding-top: 0; }
}

/* ============================================================
   ДВА РЕЖИМА ОБОЛОЧКИ — ОДНА ГРАНИЦА
   ------------------------------------------------------------
   Раньше режимы задавались в трёх файлах с разными границами: нижняя
   панель пропадала на 768, выдвижное меню работало до ~1280, а постоянное
   боковое появлялось ещё позже. В промежутке 768–1279 у человека не было
   ни постоянного меню, ни нижней панели — только бургер, и понять, где он
   находится, было нельзя.

   Теперь граница одна: до 1023 включительно — выдвижное меню, от 1024 —
   постоянное. Селекторы с body.app-page-active, чтобы перебить
   унаследованные правила без повышения важности.
   ============================================================ */

/* ─── До 1024: выдвижное меню ─── */
@media (max-width: 1199px) {
  body.app-page-active .app-side.ws-sidebar {
    position: fixed; top: 0; bottom: 0; left: 0; right: auto;
    width: min(300px, 86vw); height: 100dvh;
    transform: translateX(-100%);
    transition: transform .22s ease;
    z-index: 1200;
  }
  body.app-page-active .app-side.ws-sidebar.open { transform: translateX(0); }
  body.app-page-active .app-topbar.ws-topbar { left: 0; }
  body.app-page-active .ws-content { margin-left: 0; }
  .ws-burger { display: inline-flex; }
  /* Кнопка сворачивания бессмысленна для выдвижного меню: оно и так
     закрывается целиком. */
  .ws-collapse-btn { display: none; }
}

/* ─── От 1024: постоянное меню ─── */
@media (min-width: 1200px) { /* было 1024: постоянная панель появлялась слишком рано */
  /* Ширину задаём числом, а не переменной оболочки: --ws-off объявлена
     на .ws-shell, а меню вынесено из потока и наследует её не всегда —
     получалось меню в 37 px. Свёрнутое состояние обрабатываем отдельным
     правилом ниже. */
  body.app-page-active .app-side.ws-sidebar {
    position: fixed; top: 0; bottom: 0; left: 0; right: auto;
    width: 220px; height: 100vh; height: 100dvh;
    transform: none; z-index: 60;
  }
  body.app-page-active .ws-shell[data-collapsed="1"] .app-side.ws-sidebar { width: 68px; }
  body.app-page-active .app-topbar.ws-topbar { left: 220px; }
  body.app-page-active:has(.ws-shell[data-collapsed="1"]) .app-topbar.ws-topbar { left: 68px; }
  body.app-page-active .ws-content { margin-left: 220px; }
  body.app-page-active .ws-shell[data-collapsed="1"] .ws-content { margin-left: 68px; }
  .ws-burger { display: none; }
  .ws-collapse-btn { display: flex; }
  /* Затемнение под выдвижным меню на широком экране не нужно. */
  body.app-page-active .app-side-backdrop { display: none; }
}

/* ─── Нижняя панель: только телефон ───
   На планшете она отнимает высоту, а разделов в ней всего четыре из
   пятнадцати — на 768+ проще открыть полное меню бургером. */
@media (min-width: 768px) {
  body.app-page-active .ds-bottomnav { display: none; }
}
@media (max-width: 767px) {
  body.app-page-active .ds-bottomnav { display: flex; }
}

/* ─── Планшет 768–1023: выдвижное меню, но плотность уже не телефонная ─── */
@media (min-width: 768px) and (max-width: 1199px) {
  .ws-content { padding: 18px 20px 24px; padding-top: calc(var(--ws-topbar-h) + 18px); }
  body.app-page-active .app-topbar.ws-topbar { height: 60px; --ws-topbar-h: 60px; }
  /* Кнопки не растягиваем на всю ширину: в двухколоночной сетке это
     выглядит как ошибка вёрстки. */
  .ws-card-empty .ws-btn, .ws-empty .ws-btn { width: auto; }
  .ws-attn-item .ws-btn-sm { width: auto; }
  .ws-attn-item { flex-wrap: nowrap; }
  .ws-donut-wrap { flex-direction: row; align-items: center; }
}

/* ============================================================
   МОБИЛЬНАЯ И ПЛАНШЕТНАЯ АДАПТАЦИЯ КАБИНЕТА
   ------------------------------------------------------------
   Замер показал: настоящих переполнений было два, и оба — ряды чипов,
   которым внешние правила сбрасывали перенос в nowrap. Ряд уезжал за
   правый край, часть вариантов оказывалась недостижима, и появлялась
   горизонтальная прокрутка всей страницы.

   Правим именно перенос, а не прячем прокруткой: скрытые за краем
   фильтры человек просто не находит.
   ============================================================ */
@media (max-width: 767px) {
  /* Ряды выбора: переносим, а не прячем. */
  .ws-shell .ws-filters,
  .ws-shell .wf-templates-bar,
  .ws-shell .wf-presets,
  .ws-shell .gsc-cards,
  .ws-shell .ws-chip-row {
    flex-wrap: wrap;
    overflow-x: visible;
  }
  .ws-shell .ws-filter,
  .ws-shell .wf-tpl-chip { flex: 0 0 auto; max-width: 100%; }

  /* Заголовок раздела и действие рядом с ним не должны тесниться
     в одну строку: кнопка уезжала под край. */
  .ws-page-head { flex-direction: column; align-items: stretch; gap: 10px; }
  .ws-page-head > button,
  .ws-page-head .ws-btn { width: 100%; }

  /* Крупные действия во всю ширину — по ним проще попасть пальцем. */
  .ws-card-empty .ws-btn,
  .ws-empty .ws-btn { width: 100%; max-width: 320px; }

  /* Плотность: на узком экране 24 px по краям съедают половину строки. */
  .ws-content { padding: 14px; padding-top: calc(var(--ws-topbar-h) + 14px); }
  .ws-card { padding: 14px; }
  .ws-dash-row { gap: 12px; margin-bottom: 12px; }

  /* Кольцо позиций и легенда: в строку они не помещаются. */
  .ws-donut-wrap { flex-direction: column; align-items: stretch; gap: 12px; }
  .ws-donut { align-self: center; }
  .ws-legend { min-width: 0; }

  /* Форма задачи и поля ввода на всю ширину. */
  .ws-task-form .ws-form-row { grid-template-columns: 1fr; }
  /* Ограничение ширины полей задано в разметке инлайном (max-width:280px),
     поэтому перебиваем его селектором с более высокой специфичностью,
     а не флагом важности: флаг пришлось бы снимать таким же флагом. */
  .ws-shell .ws-card .ws-input,
  .ws-shell .ws-card select,
  .ws-shell .ws-card textarea { max-width: 100%; width: 100%; }

  /* Нижняя панель навигации перекрывала конец страницы. */
  .ws-content { padding-bottom: 84px; }
}

/* ── Планшет: ни «десктоп в миниатюре», ни «растянутый телефон» ── */
/* ЕДИНОЕ правило ширин кабинета:
     0–767     телефон, выдвижное меню + нижняя панель
     768–1199  планшет, выдвижное меню без нижней панели
     ≥1200     настольный, постоянное меню
   Раньше границы 1023/1024/768 задавались в трёх файлах по-разному, и на
   1024 внезапно появлялась постоянная панель в 220 px. */
@media (min-width: 768px) and (max-width: 1199px) {
  /* Меню остаётся выдвижным до 1024: постоянная панель в 220 px
     отнимает треть ширины, и карточки становятся нечитаемыми. */
  .ws-shell { --ws-off: 0px; }
  .ws-sidebar {
    transform: translateX(-100%);
    width: min(300px, 80vw);
    box-shadow: var(--ws-shadow-lg);
  }
  .ws-sidebar.open { transform: none; }
  body.app-page-active .app-topbar.ws-topbar { left: 0; }
  .ws-content { margin-left: 0; }
  .ws-burger { display: inline-flex; }

  /* Две колонки — читаемый компромисс на этой ширине. */
  .ws-dash-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ws-quick-row { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .ws-grid-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ws-tile-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  /* Карточки одного ряда одной высоты, иначе ряд рассыпается. */
  .ws-card-tall { min-height: 300px; }
  .ws-dash-row.second .ws-card { min-height: 200px; }
  .ws-content { padding: 18px; padding-top: calc(var(--ws-topbar-h) + 18px); }
}

/* Нижняя панель нужна только на телефоне: на планшете есть выдвижное меню
   со всеми разделами, и дублировать четыре пункта незачем. */
@media (min-width: 768px) { .app-page-active .ds-bottomnav { display: none; } }
/* Нижняя панель — только телефон. */

/* ── Порядок наложений. Значения выстроены по возрастанию, чтобы панель
      не наползала на затемнение и наоборот. ── */
.ws-sidebar { z-index: 1200; }
/* Затемнение и нижняя панель — элементы кабинета, но их классы не имеют
   префикса ws-. Ограничиваем страницей кабинета, чтобы правило не могло
   задеть публичную часть. */
.app-page-active .app-side-backdrop { z-index: 1150; }
body.app-page-active .app-topbar.ws-topbar { z-index: 1100; }
.ws-topbar .app-create-menu,
.ws-topbar .notif-dropdown,
.ws-topbar .app-avatar-menu,
.ws-topbar .app-proj-dropdown { z-index: 1120; }
.cmd-overlay { z-index: 1300; }
.app-page-active .ds-bottomnav { z-index: 1000; }

/* Выпадающие панели шапки не должны выходить за экран. */
@media (max-width: 767px) {
  .ws-topbar .app-create-menu,
  .ws-topbar .notif-dropdown,
  .ws-topbar .app-avatar-menu,
  .ws-topbar .app-proj-dropdown {
    position: fixed; left: 8px; right: 8px; top: calc(var(--ws-topbar-h) + 6px);
    width: auto; max-width: none; max-height: 70vh; overflow-y: auto;
  }
}

/* Безопасная зона на iPhone: нижняя панель и баннер прижимались к самому
   краю и попадали под системную полосу жеста. */
@supports (padding: max(0px)) {
  .app-page-active .ds-bottomnav { padding-bottom: max(6px, env(safe-area-inset-bottom)); }
  #page-app .cookie-banner,
  .app-page-active .cookie-banner { bottom: max(84px, calc(env(safe-area-inset-bottom) + 84px)); }
}

/* ═══ Панель уведомлений на телефоне ═══
   Заголовок и «Отметить все прочитанными» стояли в одной строке и
   налезали друг на друга: длинная подпись кнопки не помещалась рядом
   с заголовком. Переносим кнопку под заголовок и разрешаем перенос
   текста — обрезать подпись нельзя, она объясняет действие. */
@media (max-width: 767px) {
  .ws-topbar .notif-head {
    display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
    padding: 12px 14px;
  }
  .ws-topbar .notif-head h3 { font-size: 15px; margin: 0; }
  .ws-topbar .notif-head button {
    font-size: 12.5px; white-space: normal; text-align: left; padding: 0;
  }
  .ws-topbar .notif-list { max-height: 50vh; overflow-y: auto; }
  .ws-topbar .notif-foot { padding: 10px 14px; }
}
/* Кнопка колокольчика при открытой панели — видимое состояние. */
.ws-topbar #appNotifBtn[aria-expanded="true"] {
  background: var(--ws-primary-soft);
  border-color: var(--ws-primary);
  color: var(--ws-primary);
}

/* ═══ Cookie на телефоне ═══
   Нижний лист над навигацией: сверху он спорил бы с шапкой, а по центру
   перекрывал бы рабочие кнопки. При открытой панели или уведомлениях
   уводим его вниз — иначе он всплывает поверх того, с чем человек
   сейчас работает. */
@media (max-width: 767px) {
  .app-page-active .cookie-banner {
    left: 8px; right: 8px; bottom: 84px; top: auto;
    max-width: none; width: auto; border-radius: 14px; padding: 12px 14px;
    font-size: 12.5px;
  }
  body.drawer-open .app-page-active .cookie-banner,
  body.drawer-open .cookie-banner,
  body.overlay-open .cookie-banner { opacity: 0; pointer-events: none; }
}

/* ═══ Публичная шапка внутри кабинета ═══
   Скрываем структурно, а не медиазапросом: иначе на части ширин
   публичный бургер оказывался видимым одновременно с кабинетным,
   и на экране было два триггера одного действия. */
body.app-page-active > .pub-header,
body.app-page-active .pub-header,
body.app-page-active #burgerBtn,
body.app-page-active #mobileMenu,
body.app-page-active #mobileBackdrop { display: none; }

/* ═══ Выпадающие панели шапки на телефоне ═══
   На реальном устройстве панели уведомлений и профиля уезжали за ЛЕВЫЙ край
   экрана: они привязаны к своей кнопке через right:0, а кнопка стоит почти
   у правого края — при ширине панели ~340 px её левая граница уходила
   в минус. Текст обрезался: «тметить все / очитанными», «@mail.ru».

   На телефоне отвязываем панель от кнопки и растягиваем на всю ширину
   с полями по 10 px: так она гарантированно помещается при любой ширине
   и любой длине содержимого. */
@media (max-width: 767px) {
  /* Целимся по идентификаторам: панелей уведомлений в документе две —
     публичная и кабинетная, и селектор по классу попадал не в ту.
     Настоящая кабинетная уезжала на left:-78px, обрезая текст. */
  body.app-page-active #appNotifDropdown,
  body.app-page-active #appAvatarMenu,
  body.app-page-active #appCreateMenu,
  body.app-page-active #appProjDropdown,
  body.app-page-active .ws-topbar .notif-dropdown,
  body.app-page-active .ws-topbar .app-avatar-menu,
  body.app-page-active .ws-topbar .app-create-menu,
  body.app-page-active .ws-topbar .app-proj-dropdown {
    position: fixed;
    left: 10px; right: 10px; top: calc(var(--ws-topbar-h, 56px) + 8px);
    width: auto; min-width: 0; max-width: none;
    max-height: calc(100vh - var(--ws-topbar-h, 56px) - 100px);
    overflow-y: auto;
    transform: none;
    border-radius: 14px;
  }
  /* Содержимое не должно обрезаться по горизонтали. */
  body.app-page-active #appNotifDropdown *,
  body.app-page-active #appAvatarMenu * { max-width: 100%; }
  body.app-page-active #appAvatarMenu .user-name-lg,
  body.app-page-active #appAvatarMenu .user-email {
    white-space: normal; word-break: break-word;
  }
}

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

   В нижней панели было пять колонок из-за пункта «Ещё». Он дублировал
   бургер, а после его удаления сетка оставила бы пустую пятую колонку
   справа. Задаём ровно четыре равные доли. */
body.app-page-active .app-topbar-right .ws-burger { margin-left: 2px; }

.app-page-active .ds-bottomnav { left: 0; right: 0; width: 100%; }
.app-page-active .ds-bottomnav-row {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0;
  width: 100%;
}
.app-page-active .ds-bottomnav-item { min-width: 0; }

/* Мягкая отметка на бургере, когда открытый раздел живёт в меню.
   Это не маршрут и не подмена активного пункта — только подсказка,
   что текущий раздел находится внутри. */
.ws-burger.has-current { position: relative; }
.ws-burger.has-current::after {
  content: ""; position: absolute; top: 5px; right: 5px;
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--ws-primary);
}

/* Правая группа шапки прижата к краю, бургер — последний в ней.
   Отступ 10 px оставляем как поле экрана, но лишний зазор убираем:
   бургер должен попадать под большой палец у самого края. */
@media (max-width: 767px) {
  body.app-page-active .app-topbar.ws-topbar { padding-left: 10px; padding-right: 10px; gap: 6px; }
  body.app-page-active .app-topbar-right { margin-left: auto; gap: 2px; }
  /* Скрытые кнопки не должны занимать место в потоке. */
  body.app-page-active .app-topbar-right > .app-topbar-create-wrap,
  body.app-page-active .app-topbar-right > .ws-usage { display: none; }

  /* Нижняя панель: собственные поля по 4 px оставляли пустую полосу
     справа после последнего пункта. Пункты занимают всю ширину, а поле
     безопасной зоны применяется только снизу. */
  .app-page-active .ds-bottomnav { padding-left: 0; padding-right: 0; }
}

/* ═══ Позиции в тёмной теме ═══
   Полоса конкурента задана светлым розовым градиентом значением, а не
   токеном: на тёмном фоне она читалась как светлый блок. Появляется
   только когда есть данные конкурентов, поэтому и не бросалась в глаза
   при обычной проверке — нашёл автоматический обход. */
html[data-theme="dark"] .pos-bar.rv {
  background: linear-gradient(180deg, #BE5A8F, #9D3B6B);
  opacity: 0.9;
}
/* Чередование строк. Полупрозрачный белый на тёмном фоне даёт светлый
   оттенок — именно его и отметил автоматический обход. На тёмной теме
   чередование должно затемнять, а не высветлять. */
html[data-theme="dark"] .pos-tr:nth-child(even):not(.pos-th) {
  background: rgba(0, 0, 0, 0.16);
}
