:root {
  color-scheme: light;
  --bg: #f7f8fa;
  --card: #ffffff;
  --text: #1a1f2e;
  --muted: #6b7280;
  --border: #e5e7eb;
  --border-light: #f1f3f5;
  --primary: #3b82f6;
  --primary-dark: #2563eb;
  --success: #10b981;
  --success-bg: #dcfce7;
  --danger: #ef4444;
  --danger-bg: #fee2e2;
  --warning: #f59e0b;
  --header: #1a1f2e;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

/* Резервируем место под вертикальный скроллбар всегда — иначе при
 * переключении skeleton ↔ полный дашборд страница то умещается в
 * viewport, то нет, scrollbar появляется/исчезает, и весь топбар
 * (право-выровненный) дёргается на ~15px. */
html { scrollbar-gutter: stable; }

/* --- Loading: thin running bar at top + skeleton shimmer --- */
.loading-bar {
  position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 9999;
  background: linear-gradient(90deg, transparent 0%, var(--success) 50%, transparent 100%);
  background-size: 50% 100%; background-repeat: no-repeat;
  animation: loading-bar-slide 1.2s linear infinite;
  pointer-events: none;
}
@keyframes loading-bar-slide {
  0%   { background-position: -50% 0; }
  100% { background-position: 150% 0; }
}

@keyframes skel-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
.skel {
  background: linear-gradient(90deg, #ecedef 25%, #f5f6f7 50%, #ecedef 75%);
  background-size: 200% 100%;
  border-radius: 4px;
  animation: skel-shimmer 1.4s ease-in-out infinite;
  display: inline-block;
}

/* Skeleton-карточка: повторяет структуру реальной (см. .card) */
.card-skel {
  background: var(--card);
  border: 1px solid var(--border);
  border-left: 3px solid #d1d5db;
  border-radius: 10px;
  padding: 12px 14px;
  min-height: 220px;
}
.card-skel .skel-title { width: 50%; height: 14px; margin-bottom: 14px; display: block; }
.card-skel .skel-section { width: 40%; height: 10px; margin: 8px 0 10px; display: block; }
.card-skel .skel-fin { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 12px; }
.card-skel .skel-fin > div { background: var(--bg); border-radius: 8px; padding: 10px 12px; }
.card-skel .skel-fin .skel-l { width: 40%; height: 9px; margin-bottom: 8px; display: block; }
.card-skel .skel-fin .skel-v { width: 70%; height: 18px; display: block; }
.card-skel .skel-tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.card-skel .skel-tiles > div { background: var(--bg); border-radius: 6px; padding: 6px 8px; }
.card-skel .skel-tiles .skel-l { width: 40%; height: 8px; margin-bottom: 5px; display: block; }
.card-skel .skel-tiles .skel-v { width: 60%; height: 14px; display: block; }

/* Empty-state когда ни одной пиццерии не выбрано */
.empty-state {
  grid-column: 1 / -1;
  display: flex; flex-direction: column;
  padding: 36px 40px; gap: 18px;
  background: var(--card); border: 1px dashed var(--border);
  border-radius: 12px;
}
.empty-state-title { font-size: 18px; font-weight: 600; color: var(--text); }
.empty-state-sub { font-size: 13px; color: var(--muted); max-width: 580px; line-height: 1.5; }
.empty-state-steps {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px;
  margin-top: 6px;
}
.empty-state-step {
  display: flex; align-items: flex-start; gap: 12px;
  background: var(--bg); border-radius: 10px;
  padding: 14px 16px;
}
.empty-state-step-num {
  flex: 0 0 28px; height: 28px; border-radius: 50%;
  background: var(--primary); color: white;
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 600; font-size: 13px;
}
.empty-state-step.is-done .empty-state-step-num {
  background: var(--success);
}
.empty-state-step-title { font-size: 14px; font-weight: 600; color: var(--text); margin-bottom: 2px; }
.empty-state-step-sub { font-size: 12px; color: var(--muted); line-height: 1.4; }

/* Подсказки в топбаре и сайдбаре, видимые только в начальном состоянии.
 * С момента появления самодостаточного empty-state («Дашборд P&L · с
 * чего начать» с тремя пронумерованными шагами) пилюли стали избыточны
 * и в Safari/Chrome выглядели громоздко. Скрыты глобально — оставлены
 * стили на случай, если решим вернуть. */
.tb-hint { display: none !important; }
.tb-hint.__keep-styles {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  font-size: 12px; font-weight: 500;
  background: #eff6ff; color: #1d4ed8;
  border: 1px solid #93c5fd;
  border-radius: 999px;
  white-space: nowrap;
  /* Внутри .panel h3 наследовалось text-transform: uppercase — гасим, чтобы
     обе подсказки выглядели одинаково (sentence-case). */
  text-transform: none; letter-spacing: 0;
  animation: tb-hint-bob 1.8s ease-in-out infinite;
}
.tb-hint-arrow { font-size: 14px; line-height: 1; }
.tb-hint-num {
  flex: 0 0 18px; height: 18px; border-radius: 50%;
  background: #1d4ed8; color: white;
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 600; font-size: 11px;
}
@keyframes tb-hint-bob {
  0%, 100% { transform: translateX(0); }
  50% { transform: translateX(-3px); }
}
/* Inline-вариант для сайдбара — без анимации (h3 уже привлекает внимание),
 * с другой направленностью «дёргания» и более компактный. */
.tb-hint.tb-hint-inline {
  margin-left: 8px;
  padding: 2px 8px;
  font-size: 11px;
  animation: none;
}
.tb-hint.tb-hint-inline .tb-hint-num {
  flex: 0 0 16px; height: 16px; font-size: 10px;
}

/* Skeleton-таблица детализации */
.table-skel-row td { padding: 6px 10px; border-bottom: 1px solid var(--border-light); }
.table-skel-row .skel-cell { display: block; height: 10px; border-radius: 3px;
  background: linear-gradient(90deg, #ecedef 25%, #f5f6f7 50%, #ecedef 75%);
  background-size: 200% 100%; animation: skel-shimmer 1.4s ease-in-out infinite; }


body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
  font-size: 14px;
  line-height: 1.5;
  min-height: 100vh;
  /* Селектор проектов спрятан под hamburger (overlay-drawer).
     Layout — одна колонка под topbar, без grid-sidebar. */
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto 1fr;  /* было 56px — двухъярусная шапка ~94px не влезала */
  grid-template-areas: "top" "main";
}

.topbar {
  grid-area: top;
  background: white;
  border-bottom: 1px solid var(--border);
  padding: 0 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  position: sticky; top: 0; z-index: 100;
}
.brand { font-size: 15px; }
.brand strong { color: var(--text); }
.muted { color: var(--muted); }

.controls {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  font-size: 13px;
  /* S13.1: расширяемся на всё доступное справа от brand и распределяем
   * left/right через space-between, чтобы скрытие LFL/⟳/freshness
   * (в Период) не двигало левый кластер. */
  flex: 1; justify-content: space-between;
}
.controls-left, .controls-right {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  /* Safari иначе растягивал .controls-left, и подсказка «Выбери»
   * улетала к правому краю кластера (в Chrome packing flex-start работал).
   * Явный flex: 0 0 auto — гарантия, что блок занимает только содержимое. */
  flex: 0 0 auto;
  justify-content: flex-start;
}

/* Топбар: блок текущего пользователя справа.
   Показывается только после успешной загрузки /auth/me — до этого .hidden. */
.user-menu {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 4px 4px 4px 10px;
  background: white;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 13px;
}
.user-menu.hidden { display: none; }
.user-menu-name {
  color: var(--text); font-weight: 500;
  max-width: 160px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.user-menu-logout {
  padding: 4px 10px;
  font-size: 12px; font-weight: 500;
  color: var(--muted);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
}
.user-menu-logout .ic-logout { display: none; }  /* десктоп — текст «Выйти» */
.user-menu-logout:hover {
  color: var(--danger);
  border-color: var(--border);
  background: #fef2f2;
}
.controls label { display: inline-flex; align-items: center; gap: 6px; }
.controls label.inline { font-weight: 400; }

/* Подпись «МЕСЯЦ» возле селектора. Стиль B2B-капитель: uppercase
 * + letter-spacing + muted-цвет — заметнее обычного 13px-текста,
 * но не давит на основной контент. */
.tb-field-label > span:first-child {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--muted);
}

input[type="date"], select {
  padding: 5px 8px; border: 1px solid var(--border);
  border-radius: 6px; font: inherit; font-size: 13px;
  background: white;
}

/* Safari (и Firefox) рисует на <select> свои нативные стрелки + синюю
 * подложку, игнорируя border-radius — селектор «выпадает» из стиля
 * остальных контролов топбара. Сбрасываем appearance и подставляем
 * единый шеврон через background-image (inline SVG, ничего не грузит). */
select {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath fill='none' stroke='%236b7280' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' d='M1 1l4 4 4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-right: 28px;
}
/* Убираем нативный «outline» от стрелки в IE/Edge */
select::-ms-expand { display: none; }

button {
  padding: 6px 14px; border-radius: 6px; border: 1px solid var(--border);
  background: white; cursor: pointer; font: inherit; font-size: 13px;
  font-weight: 500; transition: background .15s;
}
button:hover { background: var(--bg); }
.btn-primary {
  background: var(--primary); color: white; border-color: var(--primary);
}
.btn-primary:hover { background: var(--primary-dark); }
/* Кнопка «Применить» в режиме «Период»: приглушена, пока диапазон не
   менялся; акцент + кольцо, когда есть несохранённый выбор. */
.period-apply-btn { white-space: nowrap; }
.period-apply-btn:not(.is-dirty) { opacity: 0.55; }
.period-apply-btn.is-dirty { box-shadow: 0 0 0 3px rgba(37,99,235,0.28); }
.btn-secondary { border-color: var(--border); }
/* <a class="btn-secondary"> должен выглядеть как кнопка, не как ссылка.
   Используется для «⚙ Настройки» в правом кластере топбара. */
a.btn-secondary {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 10px; min-height: 32px;
  background: white;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 13px; font-weight: 500;
  color: var(--text);
  text-decoration: none;
  transition: background-color .12s;
}
a.btn-secondary:hover { background: var(--bg); }

/* --- Ops freshness indicator (S3.6) --- */
.ops-refresh-btn {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 10px;
  font-size: 13px;
}
.ops-refresh-btn .ic-refresh {
  width: 13px; height: 13px; flex-shrink: 0; color: var(--muted);
}
.ops-refresh-btn:hover .ic-refresh { color: inherit; }
.ops-refresh-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.ops-refresh-btn.spinning .ic-refresh {
  animation: ops-spin 0.8s linear infinite;
}
@keyframes ops-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }

.ops-freshness {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; line-height: 1.4;
  /* Унифицируем высоту с селектом и кнопкой Метрики (~30px) и
   * выравниваем border-radius — раньше топбар выглядел как зоопарк
   * из элементов разной формы и высоты (S3.6 + S12.2 + UX-5). */
  padding: 5px 10px;
  border: 1px solid;
  border-radius: 6px;
  min-width: 168px;
  justify-content: center;
}

/* Pill-segment toggle [День][Месяц][Период] — общий стиль с /board.
 * Активная кнопка — синяя, как «День» на /board. */
.mode-toggle {
  display: inline-flex; gap: 0;
  background: rgba(0,0,0,0.04);
  border-radius: 8px;
  padding: 3px;
  font-size: 13px;
  flex-shrink: 0;
}
.mode-toggle-btn {
  border: 0; background: transparent; cursor: pointer;
  padding: 6px 12px; border-radius: 6px;
  min-height: 30px; font-family: inherit;
  font-size: 13px; font-weight: 500;
  color: var(--muted);
  text-decoration: none; line-height: 1;
  display: inline-flex; align-items: center;
  transition: background-color .12s, color .12s;
}
.mode-toggle-btn:hover:not(.is-active) { color: var(--text); }
.mode-toggle-btn.is-active {
  background: #2563eb; color: white;
  box-shadow: 0 1px 2px rgba(37,99,235,0.25);
}

/* UX-5: LFL-toggle как сегментная кнопка-pill вместо мелкого чекбокса. */
.lfl-toggle {
  display: inline-flex; align-items: center;
  cursor: pointer; user-select: none;
}
.lfl-toggle input[type="checkbox"] {
  position: absolute; opacity: 0; pointer-events: none;
}
.lfl-pill {
  display: inline-flex; align-items: center; gap: 6px;
  /* Подгоняем под высоту селекта/кнопки/бейджа (~30px) и выравниваем
   * скругление с остальным топбаром (раньше было 999px — выбивалось). */
  padding: 5px 12px;
  font-size: 13px; line-height: 1.3;
  background: var(--bg, #f9fafb);
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 6px;
  color: var(--muted, #6b7280);
  transition: background-color .12s ease, border-color .12s ease, color .12s ease;
}
.lfl-pill-label { font-weight: 600; letter-spacing: .3px; }
.lfl-pill-state { font-weight: 500; }
.lfl-pill-state::before {
  content: ""; display: inline-block;
  width: 8px; height: 8px; border-radius: 50%;
  background: currentColor; opacity: .35;
  margin-right: 5px; vertical-align: middle;
}
.lfl-toggle input:checked + .lfl-pill {
  background: #eff6ff;
  border-color: #93c5fd;
  color: #1d4ed8;
}
.lfl-toggle input:checked + .lfl-pill .lfl-pill-state::before { opacity: 1; }
.lfl-toggle:hover .lfl-pill {
  border-color: #cbd5e1;
}
.lfl-toggle input:focus-visible + .lfl-pill {
  outline: 2px solid #93c5fd; outline-offset: 2px;
}
.ops-freshness::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  display: inline-block; background: currentColor;
}
/* Палитра подобрана под существующие .tile-ok/.tile-bad — emerald/coral,
 * не лайм/жжёный-янтарь. */
.ops-freshness.f-green { background: #ecfdf5; border-color: #a7f3d0; color: #047857; }
.ops-freshness.f-amber { background: #fffbeb; border-color: #fde68a; color: #92400e; }
.ops-freshness.f-red   { background: #fef2f2; border-color: #fecaca; color: #b91c1c; }
.ops-freshness.f-gray  { background: var(--bg); border-color: var(--border); color: var(--muted); }
.ops-freshness.f-green::before { background: #047857; }
.ops-freshness.syncing::before { animation: ops-sync-pulse 1s ease-in-out infinite; }
@keyframes ops-sync-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.3; } }
.ops-freshness.f-amber::before { background: #b45309; }
.ops-freshness.f-red::before   { background: #b91c1c; }
.ops-freshness.f-gray::before  { background: var(--muted); }
.hidden { display: none !important; }

.panel {
  /* Всегда off-canvas overlay (как раньше было только на мобильном) */
  position: fixed;
  top: var(--topbar-h, 56px);
  left: 0;
  width: min(280px, 80vw);
  height: calc(100vh - var(--topbar-h, 56px));
  height: calc(100dvh - var(--topbar-h, 56px)); /* dvh = видимая высота на мобиле (тулбары браузера), иначе sticky «Применить» уезжает за экран */
  background: white;
  border-right: 1px solid var(--border);
  padding: 16px;
  overflow-y: auto;
  /* ВЫШЕ backdrop (z=99)! При 90 затемнение ложилось ПОВЕРХ панели и
     съедало все клики по тумблерам — «селектор не работает» на десктопе.
     В mobile-@media уже было 100, поэтому на телефонах работало. */
  z-index: 100;
  transform: translateX(-100%);
  transition: transform 0.22s ease;
}
body.drawer-open .panel { transform: translateX(0); }
.panel-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 10px;
}
.panel-head h3 { margin-bottom: 0; }
.panel h3 {
  font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .5px; color: var(--muted); margin-bottom: 10px;
}
/* × закрытия панели — как drawer-close у Пульса */
.drawer-close {
  background: none; border: 0; cursor: pointer;
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 20px; color: var(--muted); border-radius: 4px;
}
.drawer-close:hover { background: rgba(0,0,0,0.05); color: var(--text); }
.projects-list label {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 4px; cursor: pointer; font-size: 13px;
  border-radius: 4px;
}
.projects-list label:hover { background: var(--bg); }

/* Группы проектов в сайдбаре — сворачиваемые секции по project_group_title.
   Каждая группа: clickable header с кареткой + счётчик «выбрано/всего» +
   actions «Все/Никого» и список чекбоксов под ним. */
.proj-group { margin-bottom: 6px; }
.proj-group-head {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 4px;
  font-size: 11px; font-weight: 600;
  color: var(--text);
  text-transform: uppercase; letter-spacing: .3px;
  cursor: pointer;
  user-select: none;
  border-radius: 4px;
}
.proj-group-head:hover { background: var(--bg); }
.proj-group-caret {
  display: inline-block; width: 10px; flex-shrink: 0;
  font-size: 10px; color: var(--muted);
}
.proj-group-title {
  flex: 1 1 auto;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.proj-group-count {
  font-weight: 500;
  color: var(--muted);
  font-size: 10px;
  letter-spacing: 0;
}
.proj-group-body { padding-left: 4px; }
.proj-group-body[hidden] { display: none; }
/* Строка проекта: тумблер слева + имя с отступом (tree-view).
   Вся строка — label: клик по имени тоже переключает тумблер
   (UX P0: switch 28×16 слишком мелкий тач-таргет сам по себе). */
.proj-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 4px 4px 24px;
  border-radius: 3px;
  cursor: pointer;
  font-size: 12px;
  line-height: 1.3;
  user-select: none;
}
.proj-row:hover { background: var(--bg, #f3f4f6); }
@media (max-width: 768px) {
  /* Apple HIG: тач-таргет ≥44px. Строка целиком кликабельна. */
  .proj-row { padding: 11px 8px 11px 24px; min-height: 44px; font-size: 13px; }
}
.proj-row .proj-name {
  flex: 1 1 auto;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--text);
}
/* Чтобы клик на тумблер группы не сворачивал группу */
.proj-group-head .switch { flex-shrink: 0; }
.proj-group-actions {
  display: flex; gap: 4px;
  padding: 4px 4px 6px;
}
.proj-group-actions button {
  flex: 1;
  font-size: 10px;
  padding: 2px 6px;
  border-radius: 3px;
  font-weight: 500;
}

.workspace {
  grid-area: main;
  padding: 20px;
  overflow-y: auto;
}

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));
  gap: 14px;
  margin-bottom: 20px;
}
.card {
  background: white; border-radius: 10px; padding: 14px;
  border-left: 4px solid var(--border);
  box-shadow: 0 1px 2px rgba(0,0,0,.04);
  display: flex; flex-direction: column; gap: 10px;
}
.card.profit { border-left-color: var(--success); }
.card.loss { border-left-color: var(--danger); }
.card-title {
  font-size: 14px; font-weight: 700;
  color: var(--text);
}

/* ---- Блок внутри карточки ---- */
.card-block {
  display: flex; flex-direction: column; gap: 6px;
}
.card-block-head {
  font-size: 10px; font-weight: 600; color: var(--muted);
  text-transform: uppercase; letter-spacing: .4px;
}

/* ---- Grid плиток ---- */
.tile-grid {
  display: grid;
  gap: 6px;
}
.tile-grid-metrics {
  /* Flex, а не grid: плитки растягиваются на всю ширину КАЖДОЙ строки,
     в т.ч. при ручном разрыве (.tile-row-break). С grid auto-fit разрыв
     форсировал материализацию всех колонок → неполные ряды оставляли
     «дырку» справа. */
  display: flex;
  flex-wrap: wrap;
}
.tile-grid-metrics > .tile {
  flex: 1 1 84px;
  min-width: 84px;
}
.tile-grid-metrics > .tile-row-break {
  flex: 0 0 100%;   /* перенос строки: занимает всю ширину, высота 0 */
  min-width: 0;
}
/* S16.5: разделитель строк в попапе «⚙ Метрики». Невидимый элемент,
   принудительно занимает всю ширину ряда CSS Grid — следующая плитка
   гарантированно пойдёт с новой строки. */
.tile-row-break {
  grid-column: 1 / -1;
  height: 0;
  margin: 0;
  padding: 0;
  border: 0;
}
.tile-grid-fin {
  /* Выручка, Маржин, EBITDA, Net — 2 в ряд */
  grid-template-columns: repeat(2, 1fr);
}

/* ---- Плитка ---- */
.tile {
  background: #f9fafb;
  border: 1px solid var(--border-light);
  border-radius: 6px;
  padding: 6px 8px;
  display: flex; flex-direction: column; gap: 1px;
  min-width: 0;
  position: relative;
}
/* Красная «K» в углу плитки — применён налоговый коэффициент (KC/DC). */
.tile-coeff-badge {
  position: absolute;
  top: 3px; right: 5px;
  font-size: 10px; font-weight: 800; line-height: 1;
  color: #dc2626;
}
/* Баннер-подсказка о привязке Dodo IS (SSO) — фиксирован у нижнего края
   экрана (в grid-потоке body его выбрасывало в самый низ длинной страницы). */
.sso-banner[hidden] { display: none; }  /* атрибут hidden должен перебивать display:flex */
.sso-banner {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 200;
  display: flex; align-items: center; gap: 12px;
  background: #eff6ff; border-top: 1px solid #bfdbfe;
  color: #1e3a8a; font-size: 13px; padding: 10px 16px;
  box-shadow: 0 -2px 8px rgba(0,0,0,0.07);
}
.sso-banner-link {
  font-weight: 600; color: #1d4ed8; text-decoration: none;
  border: 1px solid #bfdbfe; border-radius: 5px; padding: 4px 10px; background: #fff;
}
.sso-banner-link:hover { background: #dbeafe; }
.sso-banner-close {
  margin-left: auto; background: none; border: none; font-size: 18px;
  line-height: 1; color: #1e3a8a; cursor: pointer; opacity: .7;
}
.sso-banner-close:hover { opacity: 1; }
/* Lite-режим (нет PlanFact): компактный бейдж в тулбаре, слева от ⚙ Метрики */
.lite-badge {
  margin-left: auto;            /* в панели сервиса — к правому краю */
  display: inline-flex; align-items: center; gap: 5px;
  background: #eff6ff; border: 1px solid #bfdbfe; border-radius: 999px;
  color: #1e3a8a; font-size: 12px; font-weight: 600;
  padding: 3px 10px; cursor: help;
}
.lite-badge::before { content: "●"; color: #3b82f6; font-size: 9px; line-height: 1; }
.apply-short { display: none; }  /* «Ok» — только на мобайле (см. @media) */

/* ── Платформенная шапка: 2 яруса (бренд+сервисы / панель сервиса) ── */
.topbar {
  flex-direction: column; align-items: stretch; justify-content: flex-start;
  gap: 0; padding: 0; flex-wrap: nowrap;
}
.platform-bar {
  display: flex; align-items: center; gap: 12px;
  padding: 0 20px; height: 50px;   /* фикс. высота — не прыгает между сервисами */
  background: var(--card);
  border-bottom: 1px solid var(--border);
}
.service-bar {
  display: flex; align-items: center; gap: 12px;
  padding: 0 20px; height: 52px;   /* фикс. высота — как tier-2 Пульса */
  background: var(--card);  /* непрозрачная, как у Пульса */
}
.pb-spacer { flex: 1 1 auto; }
.dt-brand {
  font-size: 17px; font-weight: 700; letter-spacing: -.3px;
  color: var(--text); text-decoration: none; flex-shrink: 0;
}
.dt-brand span { color: #2563eb; }
.pb-link { white-space: nowrap; }

.svc-switch { position: relative; flex-shrink: 0; }
.svc-chip {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  font-family: inherit; font-size: 14px; font-weight: 500;
  color: #1d4ed8; background: #eff6ff; border: 1px solid #bfdbfe;
  border-radius: 8px; padding: 5px 10px;
}
.svc-chip:hover { background: #dbeafe; }
.svc-chip-caret { opacity: .65; }
.svc-menu {
  position: absolute; top: calc(100% + 6px); left: 0; min-width: 200px;
  background: #fff; border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0,0,0,.12); padding: 6px; z-index: 300;
}
.svc-menu.hidden { display: none; }
.svc-item {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 8px 10px; border-radius: 6px; text-decoration: none;
  color: var(--text); font-size: 14px;
}
.svc-item:hover { background: var(--bg); }
.svc-item.is-current { color: #1d4ed8; font-weight: 500; }
.svc-item-hub { color: var(--muted); font-size: 13px; }
.svc-item-locked { color: var(--muted); cursor: default; }
.svc-item-locked:hover { background: none; }
.svc-lock { font-size: 11px; color: var(--muted); }

/* Заглушка «модуль не подключён» (enforcement лицензий, 402) */
.license-stub { display: flex; justify-content: center; padding: 48px 16px; }
.license-stub.hidden { display: none; }
.license-stub-card {
  max-width: 440px; text-align: center;
  background: var(--card); border: 1px solid var(--border);
  border-radius: 14px; padding: 32px 28px;
}
.license-stub-ic { color: var(--primary); margin-bottom: 6px; }
.license-stub-card h2 { font-size: 18px; margin: 4px 0 8px; color: var(--text); font-weight: 600; }
.license-stub-card p { color: var(--muted); font-size: 14px; line-height: 1.5; margin: 0 0 20px; }
.license-stub-cta { display: inline-block; text-decoration: none; padding: 10px 22px; }
body.license-blocked .kpi-toolbar,
body.license-blocked .cards,
body.license-blocked #chartsGrid,
body.license-blocked .charts-toolbar,
body.license-blocked .table-wrap { display: none !important; }
.svc-menu-sep { height: 1px; background: var(--border); margin: 6px 4px; }
.svc-hint {
  position: absolute; top: calc(100% + 6px); left: 0; width: 234px;
  display: flex; gap: 8px; align-items: flex-start;
  background: #1e293b; color: #fff; font-size: 12px; line-height: 1.4;
  border-radius: 8px; padding: 8px 10px; z-index: 290;
  box-shadow: 0 6px 18px rgba(0,0,0,.18);
}
.svc-hint.hidden { display: none; }
.svc-hint b { color: #fff; font-weight: 600; }
.svc-hint button {
  margin-left: auto; background: none; border: none; color: #cbd5e1;
  font-size: 16px; line-height: 1; cursor: pointer; padding: 0; flex-shrink: 0;
}

@media (max-width: 640px) {
  .platform-bar, .service-bar { padding-left: 12px; padding-right: 12px; gap: 8px; }
  /* Ярус 2 на мобайле — в 2 ряда (без горизонт. скролла):
       ряд A: ☰ + Месяц/Период + LFL + Обновить
       ряд B: выбор месяца(ев) + Применить
     controls-left → display:contents, чтобы его дети встали во флекс панели
     и распределились по рядам через order + принудительный перенос (::after). */
  .service-bar { flex-wrap: wrap; height: auto; min-height: 52px;
                 padding-top: 6px; padding-bottom: 6px; row-gap: 8px; }
  .service-bar .controls-left { display: contents; }
  .drawer-toggle   { order: 1; }
  .mode-toggle     { order: 2; }
  .lfl-toggle      { order: 3; margin-left: auto; }  /* LFL+Обновить — к правому краю ряда A */
  .ops-refresh-btn { order: 4; }
  .ops-freshness   { order: 4; }
  .lite-badge      { order: 4; }              /* margin-left:auto уводит вправо ряда A */
  .service-bar::after { content: ""; flex-basis: 100%; height: 0; order: 5; }
  #monthFieldSingle, #monthFieldFrom, #monthFieldTo { order: 6; }
  #periodApplyBtn  { order: 7; }
  #tbHintPeriod    { order: 8; }
  /* «Применить» → «Ok» на мобайле, чтобы ряд B влез в одну строку */
  .apply-full  { display: none; }
  .apply-short { display: inline; }
  .dt-brand { font-size: 16px; }
  .user-menu-name { max-width: 90px; }
  /* Тап-таргеты ≥40px на мобайле (зону расширяем, не иконку) */
  .mode-toggle-btn { min-height: 38px; padding: 7px 12px; }
  .svc-chip { padding: 8px 10px; }
  .close-btn, .chart-modal-close, .sso-banner-close {
    min-width: 40px; min-height: 40px;
    display: inline-flex; align-items: center; justify-content: center;
  }
}
.tile-label {
  font-size: 10px; font-weight: 600; color: var(--muted);
  text-transform: uppercase; letter-spacing: .3px;
  white-space: normal;
  line-height: 1.2;
  /* Заголовок резервирует РОВНО 2 строки → значения всех плиток встают на
   * одну горизонталь (3-я строка), затем значение, затем остальное.
   * Длинные подписи клампим в 2 строки (полный текст — в title плитки). */
  min-height: 2.4em;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  flex: 0 0 auto;
}
.tile-sublabel {
  font-weight: 400; color: #9ca3af;
  text-transform: none; letter-spacing: 0;
}
.tile-value {
  /* На 1280-1366 нижняя граница 16px — иначе значения визуально
   * мельче, чем могли бы (на самом деле «11,2%» вместе с «(309)»
   * влезает и при 16-17px). На 1920 — стандартные 20px. */
  font-size: clamp(16px, 0.9vw + 3.5px, 20px);
  font-weight: 700;
  line-height: 1.2;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  /* Не ломаем строки внутри слов (иначе «зак/ч» рвётся на «зак/» + «ч»).
   * При необходимости перенос произойдёт по пробелу между числом и
   * единицей. */
  white-space: normal;
  word-break: keep-all;
  overflow-wrap: normal;
  /* flex-shrink: 0 — значение не сжимается, его высота фиксирована.
   * Вместе с flex:1 0 auto на .tile-label это даёт выравнивание
   * значений по одной горизонтали в строке плиток. */
  flex-shrink: 0;
}
.tile-unit {
  font-size: 11px; font-weight: 500; color: var(--muted);
  margin-left: 2px;
  /* Единицу всегда держим целиком («₽/ч», «зак/ч», «шт/ч»). */
  white-space: nowrap;
}
.tile-sub {
  font-size: 11px; font-weight: 500; color: var(--muted);
  margin-left: 4px;
}
.tile-sub-line {
  /* Мелкая строка под значением — для абсолютного количества (например
   * «309 шт» под «11,2 %» в Сертификатах). Не сжимается. */
  font-size: 10px;
  color: var(--muted);
  white-space: nowrap;
  flex-shrink: 0;
  line-height: 1.2;
}
.tile-hint {
  font-size: 10px; color: var(--muted);
  /* Целевые значения «цель 3 500 ₽/ч» / «цель 1,8 зак/ч» не должны
   * обрезаться эллипсисом — переносим целиком, не ломая слова. */
  white-space: normal;
  word-break: keep-all;
  min-height: 12px;
  /* Не сжимается — для выравнивания значений в строке (см. .tile-label). */
  flex-shrink: 0;
}
/* Утилита: запрещает перенос строки внутри куска (для единиц
 * с слешами «₽/ч», «зак/ч», «шт/ч» в .tile-hint). */
.tile-hint .nb,
.tile .nb { white-space: nowrap; }
/* LFL-дельта на плитках (компонент строки .tile-hint) */
.tile-delta { font-weight: 500; }
.tile-delta.pos { color: var(--success); }
.tile-delta.neg { color: var(--danger); }
.tile-ly { color: var(--muted); }

/* Цветовые зоны РКО/РС (<80 красная, 80–85 жёлтая, ≥85 зелёная).
   Применяются к ЧИСЛУ — и к основному значению, и к среднему. */
.zone-red { color: #dc2626; }
.zone-yellow { color: #d97706; }
.zone-green { color: #16a34a; }
/* Строка скользящего среднего под значением: «ср. 12 нед NN». */
.tile-avg { font-weight: 600; }
.tile-avg-lbl { color: var(--muted); font-weight: 500; }
.tile-avg-val { font-variant-numeric: tabular-nums; }

/* ---- Статусы ---- */
.tile.tile-ok {
  background: #ecfdf5; border-color: #a7f3d0;
}
.tile.tile-ok .tile-value { color: #047857; }
.tile.tile-bad {
  background: #fef2f2; border-color: #fecaca;
}
.tile.tile-bad .tile-value { color: #b91c1c; }

/* Фин-плитки — крупнее, чем метрики (тоже clamp, но с большим потолком) */
.tile-fin .tile-value { font-size: clamp(16px, 1.0vw + 4px, 22px); }
.tile-fin.tile-pos .tile-value { color: var(--success); }
.tile-fin.tile-neg .tile-value { color: var(--danger); }

/* S23: плитка «Заказы» — штуки, не ₽. Каналы — ЕДИНЫЙ грид (обе строки
 * делят колонки), числа right-align + tabular, колонка % фикс-ширины →
 * при процентах разного порядка числовые значения не сдвигаются. */
/* Грид разбивки по каналам — общий для плиток Заказы и Выручка. */
.ord-channels {
  display: grid; grid-template-columns: 1fr auto;
  column-gap: 7px; row-gap: 2px; align-items: baseline;
  margin-top: 4px; font-size: 10px;
}
.ord-channels.lfl { grid-template-columns: 1fr auto auto; }
.ord-lbl { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ord-cur,
.ord-ly,
.ord-d { font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
.ord-cur { color: var(--text); font-weight: 600; }
.ord-ly { color: var(--muted); }
.ord-d { min-width: 3.6em; }
.ord-d .tile-delta { font-size: 10px; }
/* Большой LFL-% итога — прижимаем к правому краю плитки (Заказы + Выручка). */
.tile-channels .tile-value { display: flex; align-items: baseline; }
.tile-channels .tile-value .tile-delta { margin-left: auto; font-size: 12px; }
/* Фин-плитки выравниваем по ВЕРХУ: значения Выручки и Заказов оказываются
 * на одной горизонтали, а блок каналов «Заказов» уходит вниз, не сдвигая
 * само значение. */
.tile-grid-fin .tile { justify-content: flex-start; }
.tile-grid-fin .tile-label { flex: 0 0 auto; }

/* Период: кликабельная карточка → помесячная детализация */
.card-clickable { cursor: pointer; transition: box-shadow .12s, border-color .12s; }
.card-clickable:hover { box-shadow: 0 2px 12px rgba(0,0,0,.08); border-color: var(--primary); }
.card-monthly-hint { float: right; font-size: 11px; font-weight: 600; color: var(--primary); }
.card-clickable:hover .card-monthly-hint { text-decoration: underline; }

/* Модалка «помесячно»: таблица метрики×месяцы + спарклайны */
.pm-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
/* table-layout:fixed + явные ширины колонок из <colgroup> (inline) — движок
   не распределяет «лишнее» место в колонку метрик. Ширина таблицы = сумма
   колонок (inline), поэтому slack отсутствует, а узкие экраны скроллятся. */
.pm-table {
  table-layout: fixed; border-collapse: separate; border-spacing: 0;
  font-size: 13px; font-variant-numeric: tabular-nums;
}
.pm-table th, .pm-table td {
  padding: 5px 8px; text-align: right; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
  border-bottom: 1px solid var(--border-light);
}
.pm-table thead th {
  background: #f9fafb; color: var(--muted); font-weight: 600;
  font-size: 11px; text-transform: uppercase; letter-spacing: .4px;
  position: sticky; top: 0; z-index: 1;
}
.pm-table .pm-mlabel {
  text-align: left; color: var(--text); font-weight: 500;
  white-space: normal; word-break: break-word; line-height: 1.2;
  position: sticky; left: 0; background: #fff;
}
.pm-table thead .pm-mlabel { background: #f9fafb; z-index: 2; }
.pm-table .pm-spark { color: var(--primary); padding: 5px 5px; overflow: visible; }
.pm-spark-svg { width: 100%; height: 16px; display: block; }
.pm-table tbody tr:hover td { background: #fafbfc; }
.pm-table tbody tr:hover .pm-mlabel { background: #fafbfc; }
@media (max-width: 800px) {
  .pm-table { font-size: 12px; }
  .pm-table th, .pm-table td { padding: 5px 6px; }
  .pm-table .pm-mlabel { font-size: 11.5px; }
}

.pos { color: var(--success); }
.neg { color: var(--danger); }

/* Тулбар над секцией графиков — пока содержит только конфигуратор видимости. */
.charts-toolbar {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  margin-bottom: 8px;
  position: relative; z-index: 5;
}
/* Когда попап в тулбаре открыт — поднимаем его z-index, чтобы panel
 * перекрывал соседний тулбар (например попап «⚙ Метрики» не должен
 * прятаться за кнопкой «⚙ Графики» ниже на странице). */
.charts-toolbar:has(details[open]) { z-index: 20; }
/* Тулбар над блоком карточек — то же оформление, ниже отступ. */
.kpi-toolbar { margin-bottom: 4px; gap: 8px; }

/* Ссылка «🎯 Цели» — слева от «⚙ Метрики», только десктоп, только ≥30. */
.goals-link {
  display: inline-flex; align-items: center; text-decoration: none;
  padding: 5px 12px; font-size: 12px; font-weight: 500; line-height: 1.4;
  background: white; color: var(--text);
  border: 1px solid var(--border); border-radius: 6px; user-select: none;
}
.goals-link:hover {
  background: var(--bg); border-color: var(--primary); color: var(--primary-dark);
}
.goals-link.hidden { display: none; }
@media (max-width: 760px) { .goals-link { display: none !important; } }

/* Баннер «цели на месяц не заданы» */
.goals-banner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
  background: #eff6ff; border: 1px solid #bfdbfe; color: #1e3a8a;
  border-radius: 8px; padding: 10px 14px; margin-bottom: 10px; font-size: 13px;
}
.goals-banner.hidden { display: none; }
.goals-banner-text { flex: 1 1 260px; }
.goals-banner-actions {
  display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.goals-banner-btn {
  text-decoration: none; font-size: 12px; font-weight: 600;
  padding: 6px 12px; border-radius: 6px; white-space: nowrap;
  border: 1px solid #bfdbfe; color: var(--primary-dark); background: white;
}
.goals-banner-btn.primary {
  background: var(--primary); color: white; border-color: var(--primary-dark);
}
.goals-banner-btn:hover { filter: brightness(0.97); }
.goals-banner-close {
  border: none; background: transparent; color: #64748b; cursor: pointer;
  font-size: 14px; padding: 4px; line-height: 1;
}

/* Стрелки ↑↓ в строках попапа «⚙ Метрики» / «⚙ Графики». Touch-friendly:
 * минимум 24×24 (на мобиле уйдёт до 32×32 через media query — на этом
 * этапе оставляю компактно).  */
.charts-config-row { gap: 8px; }
.cfg-row-label { flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cfg-row-arrows { display: inline-flex; gap: 2px; flex-shrink: 0; }
.cfg-arrow {
  width: 22px; height: 22px;
  padding: 0; border: 1px solid var(--border-light);
  background: white; border-radius: 4px;
  font-size: 9px; line-height: 1;
  color: var(--muted); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.cfg-arrow:hover:not(:disabled) {
  background: var(--bg); color: var(--text);
}
.cfg-arrow:disabled { opacity: 0.3; cursor: not-allowed; }

/* «⚙ Графики» — собственный popover на <details>. Раскрывается панелью с
   чекбоксами; новые пункты добавляются в JS-каталоге CHARTS. */
.charts-config { position: relative; }
.charts-config > summary {
  list-style: none; cursor: pointer;
  padding: 5px 12px;
  font-size: 12px; font-weight: 500;
  background: white; color: var(--text);
  border: 1px solid var(--border); border-radius: 6px;
  user-select: none;
  display: inline-flex; align-items: center; gap: 4px;
  transition: background .15s, border-color .15s;
}
.charts-config > summary::-webkit-details-marker { display: none; }
.charts-config > summary:hover {
  background: var(--bg);
  border-color: #c7cdd5;
}
.charts-config[open] > summary {
  background: var(--bg);
  border-color: var(--primary);
  color: var(--primary-dark);
}

.charts-config-popover {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 260px;
  background: white;
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 6px 20px rgba(0,0,0,0.10);
  padding: 10px 12px;
  z-index: 200;
}
.charts-config-head {
  font-size: 10px; font-weight: 600; color: var(--muted);
  text-transform: uppercase; letter-spacing: .4px;
  margin-bottom: 8px;
}
.charts-config-row {
  display: flex; align-items: center; gap: 8px;
  padding: 4px 4px;
  font-size: 13px; cursor: pointer;
  border-radius: 4px;
}
.charts-config-row:hover { background: var(--bg); }
.charts-config-row input { margin: 0; cursor: pointer; }
.charts-config-foot {
  display: flex; gap: 6px;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--border-light);
}
.charts-config-btn {
  flex: 1;
  font-size: 11px; padding: 4px 8px;
  border-radius: 4px;
}

.charts {
  display: grid;
  /* 320px (раньше 400) — гарантирует 3 в ряд начиная с 1280px (sidebar
   * ~240px, main ~1040px ≥ 3·320 + 2·12 = 984px). На 1920 запас большой. */
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 12px;
  margin-bottom: 20px;
}
.chart-loading {
  position: absolute;
  inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; color: var(--muted);
  background: rgba(255,255,255,0.7);
  pointer-events: none;
}
.chart-box { position: relative; }
.chart-box {
  background: white; border-radius: 10px;
  padding: 14px; box-shadow: 0 1px 2px rgba(0,0,0,.04);
  cursor: pointer;  /* клик → увеличенная версия в модалке */
  transition: box-shadow .15s;
}
.chart-box:hover { box-shadow: 0 2px 10px rgba(0,0,0,.10); }

/* Модалка увеличенного графика */
.chart-modal {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; align-items: center; justify-content: center;
}
.chart-modal.hidden { display: none; }
.chart-modal-backdrop {
  position: absolute; inset: 0; background: rgba(0,0,0,0.5);
}
.chart-modal-box {
  position: relative;
  background: white; border-radius: 14px;
  width: min(960px, 94vw); height: min(640px, 88vh);
  display: flex; flex-direction: column;
  padding: 16px 20px 20px;
  box-shadow: 0 24px 64px rgba(0,0,0,0.3);
}
.chart-modal-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 12px;
}
.chart-modal-head h3 { margin: 0; font-size: 16px; font-weight: 600; }
.chart-modal-close {
  border: none; background: none; cursor: pointer;
  font-size: 26px; line-height: 1; color: var(--muted);
  width: 36px; height: 36px; border-radius: 8px;
}
.chart-modal-close:hover { background: rgba(0,0,0,0.05); color: var(--text); }
.chart-modal-body { flex: 1; min-height: 0; position: relative; }
.chart-modal-body canvas { width: 100% !important; height: 100% !important; }
.chart-box.wide {
  grid-column: 1 / -1;
}
.chart-box h3 {
  font-size: 12px; font-weight: 600; color: var(--text);
  margin-bottom: 10px;
}
.chart-wrap { position: relative; height: 260px; }

.targets-report {
  max-height: 260px; overflow-y: auto;
}
.target-row {
  display: grid;
  grid-template-columns: 1fr 110px 90px 90px 70px;
  gap: 8px; padding: 6px 4px;
  border-bottom: 1px solid var(--border-light);
  font-size: 12px; align-items: center;
}
.target-row.over { background: var(--danger-bg); }
.target-row.ok { background: var(--success-bg); }
.target-row.header {
  font-weight: 600; color: var(--muted);
  text-transform: uppercase; letter-spacing: .3px;
  font-size: 11px; background: transparent;
}

.table-wrap {
  background: white; border-radius: 10px;
  padding: 14px; box-shadow: 0 1px 2px rgba(0,0,0,.04);
}
.table-wrap h3 {
  font-size: 13px; font-weight: 600; margin-bottom: 10px;
}
.table-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 10px;
}
.table-head h3 { margin-bottom: 0; }
.export-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px;
  font-size: 12px; font-weight: 500;
}
.export-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.modal-header-actions {
  display: inline-flex; align-items: center; gap: 8px;
}
.table-scroll { overflow-x: auto; }

table {
  width: 100%; border-collapse: collapse;
  font-size: 12px; min-width: 900px;
}
th, td {
  padding: 6px 10px; text-align: right;
  border-bottom: 1px solid var(--border-light);
  white-space: nowrap;
}
th:first-child, td:first-child {
  text-align: left; position: sticky; left: 0;
  background: inherit; min-width: 240px;
}
thead th {
  background: var(--header); color: white;
  font-weight: 600; position: sticky; top: 0;
  font-size: 11px; z-index: 2;
}
thead th:first-child { background: var(--header); z-index: 3; }

.lvl-1 { background: #eff6ff; font-weight: 700; }
.lvl-1 td:first-child { background: #eff6ff; }
.lvl-2 td:first-child { padding-left: 24px; }
.lvl-3 td:first-child { padding-left: 40px; color: var(--muted); font-size: 11px; }
.lvl-4 td:first-child { padding-left: 56px; color: var(--muted); font-size: 11px; font-style: italic; }
.summary-row {
  background: #f3f4f6; font-weight: 700;
  border-top: 2px solid #d1d5db;
}
.summary-row td:first-child { background: #f3f4f6; }
.final-row { background: var(--header); color: white; font-weight: 700; }
.final-row td:first-child { background: var(--header); color: white; }

tr.clickable { cursor: pointer; }
tr.clickable:hover { background: #f9fafb; }
tr.clickable:hover td:first-child { background: #f9fafb; }

/* Кликабельная отдельная ячейка — для drill-down с фильтром по конкретному проекту/Итого */
td.cell-clickable { cursor: pointer; }
td.cell-clickable:hover {
  background: #eff6ff !important;
  outline: 1px solid #bfdbfe;
  outline-offset: -1px;
}

.pct { font-size: 10px; color: var(--muted); display: block; }
.delta { font-size: 10px; display: block; margin-top: 2px; }
.delta.neg { color: var(--danger); }
.delta.pos { color: var(--success); }

.dash { color: #d1d5db; }
.over-target { box-shadow: inset 0 0 0 2px var(--danger); }

/* === Template-tree «Детализация по статьям» === */
.tree-col-head {
  display: flex; align-items: center; gap: 8px;
  justify-content: space-between;
}
.tree-toolbar {
  display: inline-flex; gap: 6px; align-items: center;
  font-weight: 400; text-transform: none; letter-spacing: 0;
}
.tree-toolbtn {
  background: rgba(255,255,255,0.12); color: white;
  border: 1px solid rgba(255,255,255,0.2); border-radius: 4px;
  padding: 2px 8px; font-size: 10px; cursor: pointer;
  font-family: inherit; line-height: 1.4;
}
.tree-toolbtn:hover { background: rgba(255,255,255,0.22); }
.tree-toolbtn-check {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 10px; color: rgba(255,255,255,0.9); cursor: pointer;
  user-select: none;
}
.tree-toolbtn-check input { margin: 0; transform: scale(0.9); cursor: pointer; }

/* Базовая таблица «Детализации» — табличные цифры и компактные строки. */
.table-wrap table {
  font-variant-numeric: tabular-nums;
}
.table-wrap td,
.table-wrap th { font-variant-numeric: tabular-nums; }
.table-wrap tbody td {
  padding: 5px 10px;
}

tr.tpl-row td:first-child {
  /* НЕ ставим display:flex — иначе TD теряет участие в табличном
     row-height и фон не растягивается до низа в строках, где справа
     value+% занимают две строки (Маржинальная прибыль и т.п.).
     Используем обычную table-cell верстку с inline-block детьми. */
  padding: 5px 10px;
  vertical-align: middle;
  white-space: nowrap;
}
.tpl-indent {
  /* depth × 14px — отступ под уровень. Чуть уже чем раньше, чтобы при глубокой
     вложенности (5+ уровней) дерево не съедало пол-колонки. */
  display: inline-block;
  width: calc(var(--d, 0) * 14px);
  vertical-align: middle;
}
.tpl-toggle {
  width: 28px; height: 28px; padding: 0; margin: 0 6px 0 -2px;
  background: none; border: none; cursor: pointer;
  font-size: 18px; color: var(--text); line-height: 1; font-weight: 700;
  border-radius: 5px;
  display: inline-flex; align-items: center; justify-content: center;
  vertical-align: middle;
}
.tpl-toggle:hover { color: var(--primary-dark); background: rgba(59,130,246,0.14); }
.tpl-toggle.open { color: var(--text); }
.tpl-toggle-spacer {
  display: inline-block; width: 32px;
  vertical-align: middle;
}
.tpl-title {
  display: inline-block;
  vertical-align: middle;
  white-space: nowrap;
}

/* Hover — подсвечиваем всю строку, в т.ч. sticky-колонку.
   :not(.tpl-final) — чтобы тёмная финальная строка «Чистая прибыль» при
   наведении не превращалась в светлую (белый текст становится нечитаемым). */
.table-wrap tbody tr.tpl-row:not(.tpl-final):hover td,
.table-wrap tbody tr.tpl-row:not(.tpl-final):hover td:first-child {
  background: #f3f6fa;
}

/* Итого — последняя колонка. Лёгкое отделение левой границей и
   жирные цифры, без отдельного фонового заливания (чтобы не конфликтовать
   с подсветками строк). */
.table-wrap td:last-child,
.table-wrap th:last-child {
  border-left: 1px solid var(--border);
}
.table-wrap tbody td:last-child { font-weight: 700; }

/* Уровни оформления — top-level секции «Выручка/Переменные расходы/...».
   Делаем сдержанно: серый фон, обычный регистр, тонкая верхняя граница. */
tr.tpl-h0 td {
  background: #e8edf3;
  font-weight: 700;
  border-top: 1px solid var(--border);
}
tr.tpl-h0 td:first-child { background: #e8edf3; }

/* Подсекции — без отдельной заливки: иерархию держим жирностью и отступом,
   чтобы не плодить почти одинаковые бледные тона. */
tr.tpl-h1 td {
  font-weight: 600;
}

tr.tpl-h2 td {
  font-weight: 600;
  color: var(--text);
}

tr.tpl-h3 td { font-weight: 500; }

tr.tpl-leaf { font-size: 12px; }
tr.tpl-leaf .tpl-title { color: #4b5563; }
tr.tpl-leaf:hover .tpl-title { color: var(--text); }

/* Читаемость: процент чуть крупнее, минус — темнее (контраст на мелком
   тексте). Финальную тёмную строку не трогаем — там свой светлый красный. */
.table-wrap .pct { font-size: 11px; }
.table-wrap .neg { color: #dc2626; }

/* Итоговые расчётные строки (Маржинальная / Операционная / EBITDA / Чистая
   прибыль) — стиль «summary»: голубой акцент с боковой полоской. Чётко
   отличается от серых tpl-h0 по цвету и от листьев по толщине. */
/* Итоговые расчётные строки — различаем синей полоской-акцентом + жирностью,
   на белом фоне (без отдельной заливки, чтобы не конкурировать с секциями
   и тёмной финальной строкой). Цвета — на токенах проекта. */
tr.tpl-calc td {
  font-weight: 700;
  border-top: 1px solid var(--border);
  box-shadow: inset 3px 0 0 var(--primary);
}
tr.tpl-calc .tpl-title { color: var(--text); font-style: normal; }
tr.tpl-calc .pct { color: var(--muted); }

/* Финальная строка — Чистая прибыль. Жёстче, чем обычная tpl-calc:
   тёмный фон, белый текст. Низ P&L должен быть очевиден. */
tr.tpl-calc.tpl-final td {
  background: var(--header);
  color: white;
  border-top: 2px solid #1a1f2e;
  border-bottom: none;
  box-shadow: none;
}
tr.tpl-calc.tpl-final td:first-child { background: var(--header); color: white; }
tr.tpl-calc.tpl-final td:last-child { border-left-color: rgba(255,255,255,0.18); }
tr.tpl-calc.tpl-final .tpl-title { color: white; }
tr.tpl-calc.tpl-final .pct {
  color: rgba(255,255,255,0.78);
  font-size: 11px;
  font-weight: 600;
}
tr.tpl-calc.tpl-final .neg { color: #fca5a5; }
/* Hover на финальной строке — чуть светлее, чтобы был visual feedback,
   но текст оставался белым и читаемым. */
.table-wrap tbody tr.tpl-final:hover td,
.table-wrap tbody tr.tpl-final:hover td:first-child {
  background: #2a3349;
}

/* Modal */
.modal {
  position: fixed; inset: 0; background: rgba(0,0,0,.4);
  display: flex; align-items: center; justify-content: center;
  z-index: 1000;
}
.modal.hidden { display: none; }
.modal-content {
  background: white; border-radius: 12px; padding: 20px;
  max-width: 560px; width: calc(100% - 40px); max-height: 85vh; overflow-y: auto;
}
.modal-content.wide { max-width: min(1280px, calc(100vw - 48px)); }
.modal-header {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 12px;
}
.modal-footer { margin-top: 16px; display: flex; justify-content: flex-end; }
.close-btn {
  background: none; border: none; font-size: 24px;
  cursor: pointer; padding: 0 8px; line-height: 1;
}

/* Drill-down: шапка-summary в стиле PlanFact (Проект / Период / Сумма) */
.drill-summary {
  background: #f9fafb;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 14px;
  margin-bottom: 12px;
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: 16px;
  row-gap: 4px;
  font-size: 13px;
}
.drill-sum-row { display: contents; }
.drill-sum-k { color: var(--muted); font-weight: 500; }
.drill-sum-v { color: var(--text); }
.drill-sum-v.neg { color: var(--danger); }

/* Drill-down: таблица операций. Используем фиксированную раскладку
   с клиппингом overflow + ellipsis. Длинные комментарии и контрагенты
   режутся «…», полный текст доступен через title-tooltip. */
.drill-table {
  width: 100%;
  font-size: 12px;
  border-collapse: collapse;
  table-layout: fixed;
}
.drill-table col.c-date { width: 92px; }
.drill-table col.c-cat { width: 200px; }
.drill-table col.c-proj { width: 110px; }
.drill-table col.c-ca { width: 200px; }
.drill-table col.c-comment { width: auto; }
.drill-table col.c-sum { width: 110px; }

.drill-table th,
.drill-table td {
  padding: 6px 8px;
  border-bottom: 1px solid #f3f4f6;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: middle;
}
.drill-table thead th {
  position: sticky; top: 0;
  z-index: 1;
  background: #f3f4f6;
  text-align: left;
  border-bottom: 1px solid var(--border);
  font-weight: 600;
  color: var(--text);
}
.drill-table thead th.th-sum { text-align: right; }
.drill-table tbody tr:hover td { background: #f9fafb; }
.drill-table .neg { color: var(--danger); }
.drill-table td.td-sum {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-weight: 500;
}

#targetsForm {
  display: grid; gap: 10px; max-height: 50vh; overflow-y: auto;
  margin: 12px 0; padding-right: 8px;
}
.target-input-row {
  display: grid;
  grid-template-columns: 1fr 160px 100px;
  gap: 8px; align-items: center; font-size: 13px;
}
.target-input-row input[type="number"] {
  padding: 5px 8px; border: 1px solid var(--border);
  border-radius: 6px; font: inherit; font-size: 13px;
  width: 100%;
}

/* Toast */
.toast {
  position: fixed; bottom: 20px; right: 20px;
  background: var(--header); color: white;
  padding: 10px 16px; border-radius: 8px;
  font-size: 13px; z-index: 1100;
  box-shadow: 0 4px 12px rgba(0,0,0,.2);
}
.toast.hidden { display: none; }
.toast.error { background: var(--danger); }
.toast.success { background: var(--success); }

/* ========================================================================
 * Drawer (мобильный сайдбар проектов).
 * На десктопе hamburger скрыт, .panel в гриде. На мобиле hamburger в
 * топбаре, .panel становится off-canvas drawer'ом, выезжает по тапу.
 * ======================================================================== */
.drawer-toggle {
  display: inline-flex;  /* всегда виден — drawer теперь overlay для всех */
  width: 36px; height: 36px; padding: 0;
  background: none; border: none;
  border-radius: 6px;
  align-items: center; justify-content: center;
  cursor: pointer; color: var(--text);
  flex-shrink: 0;
}
.drawer-toggle:hover { background: rgba(0,0,0,0.05); }
.drawer-backdrop {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.4);
  z-index: 99;  /* под топбаром (z=100), но над контентом */
  opacity: 0; transition: opacity 0.2s;
  pointer-events: none;
}
body.drawer-open .drawer-backdrop {
  opacity: 1; pointer-events: auto;
}

@media (max-width: 800px) {
  /* Только одна колонка контента; sidebar — оверлей.
   * grid-template-rows: auto — даём топбару расти под несколько строк
   * контролов. Высота меряется в JS и попадает в --topbar-h, чтобы
   * .panel под топбаром позиционировался корректно. */
  body { grid-template-columns: 1fr; grid-template-areas: "top" "main";
         grid-template-rows: auto 1fr; }
  /* Hamburger в топбаре */
  .drawer-toggle { display: inline-flex; }
  /* Топбар — 2-ярусный flex-column; внешних отступов/зазора нет (у ярусов
     свои паддинги и бордеры, как на десктопе). */
  .topbar { padding: 0; gap: 0; }
  .controls-left { gap: 8px; }
  /* Сайдбар — фиксированная панель слева, по умолчанию за экраном.
   * top рассчитывается от --topbar-h (на лету устанавливается JS-ом). */
  .panel {
    display: block;
    position: fixed;
    top: var(--topbar-h, 56px);
    left: 0;
    width: min(280px, 80vw);
    height: calc(100vh - var(--topbar-h, 56px));
    height: calc(100dvh - var(--topbar-h, 56px)); /* dvh: видимая высота на мобиле — sticky «Применить» остаётся на экране */
    overflow-y: auto;
    background: white;
    border-right: 1px solid var(--border);
    box-shadow: 2px 0 8px rgba(0,0,0,0.04);
    z-index: 100;  /* над основным контентом */
    transform: translateX(-100%);
    transition: transform 0.22s ease;
  }
  body.drawer-open .panel { transform: translateX(0); }
  /* На узких экранах workspace получает меньше padding */
  .workspace { padding: 12px; }
}

/* На мобиле — детализация имеет горизонтальный скролл (много колонок
 * проектов невозможно влезть). Минимальная ширина первой колонки. */
@media (max-width: 800px) {
  .table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .table-scroll table { min-width: 100%; }
  /* Drill-down модалка на мобиле — full-screen.
   * .modal-content.wide имеет более высокую специфичность (max-width
   * min(1280, 100vw-48)), поэтому явно перебиваем оба варианта. */
  .modal-content,
  .modal-content.wide {
    max-width: 100%; width: 100%;
    max-height: 100vh; height: 100vh;
    border-radius: 0;
    padding: 12px;
  }
  /* Попапы конфига (Метрики/Графики) — bottom-sheet на мобиле:
   * прижаты к низу экрана на всю ширину, легко скроллить пальцем. */
  .charts-config-popover {
    position: fixed !important;
    left: 0; right: 0; bottom: 0; top: auto !important;
    width: 100% !important;
    max-width: 100% !important;
    border-radius: 12px 12px 0 0;
    max-height: 70vh;
    overflow-y: auto;
    box-shadow: 0 -4px 16px rgba(0,0,0,0.15);
  }
  /* Стрелки ↑↓ крупнее под палец на мобиле */
  .cfg-arrow { width: 32px; height: 32px; font-size: 12px; }

  /* Карточки проектов: минимум 380px вылезал за viewport 388px (с учётом
   * padding'a workspace). Снижаем до 0 — одна карточка на всю ширину. */
  .cards { grid-template-columns: 1fr; gap: 10px; }

  /* Таблица детализации: на мобиле первый столбец «прилипает» к левому
   * краю (sticky), чтобы при горизонтальном скролле названия статей
   * оставались видны и пользователь не терял контекст. Числовые
   * столбцы съезжают вправо при скролле. */
  .table-scroll { max-width: 100%; }
  .table-scroll table { min-width: max-content; }
  .table-scroll th:first-child,
  .table-scroll td:first-child {
    position: sticky; left: 0;
    background: white;
    z-index: 5;
    /* плотная тень-«отделитель» чтобы скроллящийся контент явно
     * прятался ПОД первой колонкой, а не просвечивал через неё */
    box-shadow: 4px 0 6px -2px rgba(0,0,0,0.08);
    /* мягкий выпуск краёв первой колонки внутрь, чтобы значения
     * соседнего столбца не «прижимались» к sticky-границе */
    padding-right: 12px;
    /* ВАЖНО: ограничиваем ширину первой колонки на мобиле — иначе
     * длинные названия (типа «СТРОИТЕЛЬСТВО ПИЦЦЕРИИ, ПОКУПКА»)
     * растягивают её на 270+ px, а при max-scroll вправо все числа
     * уезжают за пределы и прячутся ПОД этой колонкой.
     * Решение: max 60% viewport, длинные названия — wrap на 2 строки
     * с line-clamp (ellipsis в конце второй). Полное название
     * доступно через title-tooltip JS-ом. */
    max-width: 60vw;
    width: 60vw;
    /* line-clamp на 2 строки даёт компромисс между сохранением
     * читаемости длинных названий и оставлением места для чисел */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    word-break: break-word;
    line-height: 1.25;
  }
  /* Заметный горизонтальный scrollbar — на iOS/Android Safari/Chrome
   * по умолчанию прячут scrollbar до момента скролла, и пользователь
   * не понимает что таблица скроллится. Делаем всегда видимый,
   * толще и в тон бренда. */
  .table-scroll {
    scrollbar-width: thin;
    scrollbar-color: var(--primary) #e5e7eb;
  }
  .table-scroll::-webkit-scrollbar {
    height: 8px;
    -webkit-appearance: none;
  }
  .table-scroll::-webkit-scrollbar-track {
    background: #e5e7eb;
    border-radius: 4px;
  }
  .table-scroll::-webkit-scrollbar-thumb {
    background: var(--primary);
    border-radius: 4px;
    min-width: 40px;
  }
  .table-scroll::-webkit-scrollbar-thumb:hover {
    background: var(--primary-dark);
  }
  /* tbody-строки с цветным фоном (calc, total, summary) сохраняют
   * свой фон при stickyness — иначе на белом sticky видны цвета. */
  .table-scroll tr.calc-row td:first-child,
  .table-scroll tr.is-calc td:first-child { background: #eff6ff; }
  .table-scroll tr.total-row td:first-child,
  .table-scroll tr.is-total td:first-child { background: #1f2937; color: white; }
  .table-scroll tr.is-summary td:first-child { background: #f3f4f6; }

  /* Empty-state «с чего начать» — 1 колонка вместо 3, плотнее padding.
   * 3 колонки в 500px дают по 130px на шаг — текст обрезается.
   * Один столбец читается естественно, картинка не теряет смысл. */
  .empty-state { padding: 18px 16px; gap: 14px; }
  .empty-state-title { font-size: 16px; }
  .empty-state-sub { font-size: 13px; }
  .empty-state-steps { grid-template-columns: 1fr; gap: 10px; }
  .empty-state-step { padding: 12px 14px; }
}

/* Очень узкие экраны (телефон) — освобождаем место в топбаре.
 * Стратегия: переводим .topbar в CSS-grid 2 строки —
 *   row 1: ☰ | brand | ⚙ | Выйти
 *   row 2: [Месяц|Период] | селект месяца | LFL
 * Так пользователь видит главное (brand + действия) сверху, а большой
 * блок выбора периода стабильно занимает вторую строку без переносов. */
@media (max-width: 600px) {
  /* .topbar остаётся 2-ярусным flex-column (platform-bar + service-bar).
     Старую grid-раскладку одностроночного хедера убрали — иначе вложенные
     бургер/контролы (теперь внутри service-bar) ломали разметку. */
  /* Подписи «МЕСЯЦ»/«с»/«по» внутри селектов скрыты — селект сам по себе
   * понятен в контексте узкого экрана. Освобождает ~50px на каждом поле. */
  .tb-field-label > span:first-child { display: none; }
  .tb-field-label { gap: 0; }
  /* Mode-toggle компактный */
  .mode-toggle-btn { padding: 5px 10px; font-size: 12px; }
  /* «не синхронизировано» badge на мобиле скрываем — не критично,
   * пользователь увидит его на десктопе. Освобождает 150+ px. */
  .ops-freshness { display: none !important; }
  /* «⚙ Настройки» в платформенной шапке — только иконка (текст в .settings-label) */
  .pb-link { padding: 6px 8px; }
  .settings-label { display: none; }
  /* User-меню: скрываем имя; «Выйти» — иконкой вместо текста */
  .user-menu-name { display: none; }
  .user-menu-logout .logout-label { display: none; }
  .user-menu-logout .ic-logout { display: inline-block; }
  .user-menu-logout { padding: 6px 8px; }
  /* LFL pill — не подписываем «выкл/вкл», только цветная точка */
  .lfl-pill-state { display: none; }
  /* «⟳ Метрики» — только иконка-стрелка */
  .ops-refresh-btn span,
  .ops-refresh-btn { font-size: 0; padding: 6px 8px; }
  .ops-refresh-btn .ic-refresh { width: 16px; height: 16px; }

  /* Onboarding-подсказки скрыты глобально (см. .tb-hint выше) — empty-state
   * сам всё рассказывает. Здесь оставляем пустое место под потенциальные
   * мобильные правки. */
}

/* Empty-state (нет выбранных пиццерий): прячем все тулбары/графики/
 * таблицу, чтобы основная карточка «с чего начать» занимала всё
 * пространство и не выглядывали пустые рамки. На мобиле особенно
 * экономит ~150px и убирает лишнюю прокрутку. */
body.is-empty-state .charts-toolbar,
body.is-empty-state .charts,
body.is-empty-state .table-wrap {
  display: none !important;
}

/* ========================================================================
   Settings page — два таба «Структура» / «Таргеты»
   ======================================================================== */
body.settings-body {
  grid-template-columns: 1fr;
  grid-template-areas: "top" "main";
}
.brand-link { color: inherit; text-decoration: none; }
.brand-link:hover { color: var(--primary); }

/* Топбар на /settings: brand · tabs · back-link.
   Tabs занимают центр через flex:1 + justify-content:center. */
.settings-topbar { gap: 12px; }
.settings-topbar .brand { flex: 0 0 auto; }
.settings-topbar .controls { flex: 0 0 auto; }
.settings-tabs {
  flex: 1 1 auto;
  display: flex; justify-content: center;
  gap: 4px;
}
.settings-tabs .tab-btn {
  padding: 6px 18px;
  font-size: 13px; font-weight: 500;
  color: var(--muted);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  cursor: pointer;
  transition: background .12s, color .12s;
}
.settings-tabs .tab-btn:hover {
  background: var(--bg);
  color: var(--text);
}
.settings-tabs .tab-btn.active {
  background: white;
  color: var(--text);
  border-color: var(--border);
  box-shadow: inset 0 -2px 0 var(--primary);
}

/* main-обёртка теперь хранит оба пэйна; видим только активный. */
.settings-page {
  grid-area: main;
  padding: 16px 24px 32px;
  max-width: 1500px;
  margin: 0 auto;
  width: 100%;
}

.tab-pane {
  display: none;
  flex-direction: column;
  gap: 24px;
  /* Единая центрированная колонка для всех вкладок. «Платформа»
     (редактор формул + справочник) — шире, см. ниже. */
  max-width: 1080px;
  margin-left: auto; margin-right: auto;
  width: 100%;
}
.tab-pane.active { display: flex; }
.tab-pane[data-pane="platform"] { max-width: 1500px; }
/* Редактор формул не должен налезать на справочник — скролл внутри. */
#metricsTableWrap { overflow-x: auto; }

/* Sticky-полоска с подсказкой и контекстом таба (месяц-пикер / методология).
   Прилипает под топбаром (56px). */
.tab-toolbar {
  position: sticky;
  top: 56px;
  z-index: 50;
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  padding: 8px 14px;
  background: rgba(247, 248, 250, 0.92);
  backdrop-filter: saturate(140%) blur(6px);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.tab-toolbar .toolbar-hint {
  font-size: 12px; color: var(--muted);
}
.tab-toolbar label.inline {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 13px; cursor: pointer; user-select: none;
}
.tab-toolbar .hint {
  display: inline-block; width: 14px; height: 14px; line-height: 14px;
  text-align: center; border-radius: 50%; background: var(--border);
  color: var(--muted); font-size: 10px; font-weight: 700;
  cursor: help;
}
.tab-toolbar .month-select {
  padding: 4px 10px; font-size: 13px;
  border: 1px solid var(--border); border-radius: 6px;
  background: white;
}

/* legacy alias — на случай если где-то ещё ссылаются на .settings-dense */
.settings-dense {
  grid-area: main;
  padding: 18px 20px;
  max-width: 1500px;
  margin: 0 auto;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

/* Блок — белая карточка без тяжёлых теней */
.dense-block {
  background: white;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}
.dense-block .block-head {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px 16px;
  padding: 10px 14px;
  background: #f9fafb;
  border-bottom: 1px solid var(--border);
}
.dense-block .block-head h2 {
  font-size: 14px; font-weight: 700; margin: 0;
  flex-shrink: 0;
}
.dense-block .block-head .block-sub {
  font-size: 12px; flex: 1 1 auto; min-width: 0;
}
.dense-block .block-head .block-inline-ctl {
  margin-left: auto; display: inline-flex; align-items: center; gap: 8px;
  font-size: 12px;
}
.dense-block .block-head .block-inline-ctl label.inline {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer; user-select: none;
}
.dense-block .block-head .hint {
  display: inline-block; width: 14px; height: 14px; line-height: 14px;
  text-align: center; border-radius: 50%; background: var(--border);
  color: var(--muted); font-size: 10px; font-weight: 700;
  cursor: help;
}

/* Body и горизонтальный скролл только внутри блока, не всей страницы */
.dense-block .block-body { padding: 0; }
/* Нетабличное тело карточки (формы, текст) — единый внутренний отступ. */
.dense-block .block-body.body-pad { padding: 14px; }
.dense-block .block-scroll-x { overflow-x: auto; }
/* Шаблон статей может быть на 80+ строк — даём ему фиксированную высоту
   с внутренним вертикальным скроллом, чтобы Проекты ниже всегда были на виду. */
.dense-block .block-scroll-y { max-height: 60vh; overflow-y: auto; }

/* Внутри табов — больше воздуха в матрицах, чем в legacy-плотной верстке. */
.tab-pane .dense-table { font-size: 13px; }
.tab-pane .dense-table thead th { padding: 8px 10px; font-size: 11px; }
.tab-pane .dense-table tbody td { padding: 6px 8px; }
.tab-pane .matrix-table .col-proj { min-width: 110px; }
.tab-pane .matrix-table .metric-col { min-width: 200px; }
/* «Профиль» — карточки во всю ширину колонки, как на остальных вкладках
   (без отдельного узкого кэпа). Содержимое форм ограничено .profile-form. */
.tab-pane[data-pane="profile"] .dense-block { width: 100%; }

/* Карточка «Смена пароля»: слева форма, справа список доступных пиццерий. */
.profile-split {
  display: flex; flex-wrap: wrap; gap: 24px 40px; align-items: flex-start;
}
.profile-split > .profile-form { flex: 0 1 400px; max-width: 440px; width: auto; }
.profile-split > .profile-aside { flex: 1 1 340px; min-width: 300px; }
.profile-aside-title {
  font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .4px; color: var(--muted); margin: 4px 0 10px;
}
.pizzeria-list {
  list-style: none; margin: 0; padding: 0;
  columns: 2; column-gap: 28px;
}
.pizzeria-list li {
  font-size: 13px; padding: 5px 2px;
  border-bottom: 1px solid var(--border-light);
  break-inside: avoid;
}
@media (max-width: 600px) {
  .profile-split > .profile-aside {
    border-top: 1px solid var(--border); padding-top: 14px; flex-basis: 100%;
  }
  .pizzeria-list { columns: 1; }
}

/* Плотная таблица — базовая */
.dense-table {
  width: auto; max-width: 100%;  /* по контенту, не растягивать на всю ширину */
  border-collapse: separate; border-spacing: 0;
  font-size: 12px;
  min-width: 0;
}
.dense-table thead th {
  background: #f9fafb;
  color: var(--muted);
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .4px;
  padding: 6px 8px;
  text-align: left;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
  vertical-align: middle;
}
.dense-table tbody td {
  padding: 3px 6px;
  border-bottom: 1px solid var(--border-light);
  vertical-align: middle;
  white-space: nowrap;
  background: white;
}
.dense-table tbody tr:hover td { background: #fafbfc; }
.dense-table tbody tr:last-child td { border-bottom: none; }
/* Не наследуем числовые правила P&L-таблицы (text-align:right + sticky
   первая колонка min-width:240px) — в админ-таблицах текст влево, без пролётов. */
.dense-table th, .dense-table td { text-align: left; }
.dense-table th:first-child, .dense-table td:first-child { min-width: 0; position: static; }

/* ---- flush-inputs (без рамки, рамка только на фокусе) ---- */
.inp-flush {
  width: 100%;
  padding: 3px 6px;
  border: 1px solid transparent;
  border-radius: 3px;
  font: inherit; font-size: 12px;
  background: transparent;
  color: var(--text);
}
.inp-flush:hover { border-color: var(--border-light); background: #fcfcfd; }
.inp-flush:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 2px rgba(59,130,246,.15);
  background: white;
}
.inp-right { text-align: right; }
.inp-center { text-align: center; }

.cell-center { text-align: center; }

/* auto-save flash */
@keyframes flashOk { 0% { background: #bbf7d0; } 100% { background: white; } }
@keyframes flashErr { 0% { background: #fecaca; } 100% { background: white; } }
.cell-flash-ok { animation: flashOk .7s ease-out; }
.cell-flash-err { animation: flashErr 1.2s ease-out; }

/* ========== Проекты ========== */
.projects-table tbody td { padding: 2px 6px; }
.projects-table .cell-name { font-weight: 500; color: var(--text); }
.projects-table tr.row-off td { color: var(--muted); }
.projects-table tr.row-off .cell-name { text-decoration: line-through; color: #9ca3af; }
.projects-table tr.row-off .inp-flush { color: #9ca3af; }

/* Toggle switch */
.switch {
  display: inline-block; position: relative;
  width: 28px; height: 16px;
}
.switch input { opacity: 0; width: 0; height: 0; position: absolute; }
.switch .slider {
  position: absolute; inset: 0;
  background: #d1d5db; border-radius: 16px;
  transition: background .15s;
  cursor: pointer;
}
.switch .slider::before {
  content: ""; position: absolute;
  top: 2px; left: 2px; width: 12px; height: 12px;
  background: white; border-radius: 50%;
  transition: transform .15s;
  box-shadow: 0 1px 2px rgba(0,0,0,.2);
}
.switch input:checked + .slider { background: var(--primary-dark); }  /* как у Пульса (#2563eb) */
.switch input:checked + .slider::before { transform: translateX(12px); }

/* ========== Матрицы (P&L и Ops) ========== */
.matrix-table .sticky-col {
  position: sticky; left: 0;
  background: white;
  z-index: 2;
  border-right: 1px solid var(--border);
}
.matrix-table thead th.sticky-col {
  background: #f3f4f6;
  z-index: 3;
}
.matrix-table .metric-col {
  min-width: 180px; text-align: left;
  font-weight: 500;
}
.matrix-table thead th.metric-col { font-weight: 600; }

.matrix-table .col-proj {
  min-width: 90px;
  max-width: 140px;
  text-align: right;
}
.matrix-table .col-proj.has-override .inp-flush {
  font-weight: 600;
  color: var(--primary-dark);
}

/* Ops и P&L матрицы — строка таргетов/дефолта */
.ops-matrix .row-head-target td,
.pnl-matrix .row-head-target td {
  background: #fef3c7;
  border-bottom: 2px solid #facc15;
}
.ops-matrix .row-head-target td.sticky-col,
.pnl-matrix .row-head-target td.sticky-col {
  background: #fef3c7;
  font-weight: 600; text-transform: uppercase; letter-spacing: .3px;
  font-size: 10px; color: #92400e;
}
.ops-matrix .target-input,
.pnl-matrix .target-input {
  font-weight: 600; color: #92400e;
}
.ops-matrix .ops-h-label,
.pnl-matrix .ops-h-label {
  font-size: 11px; font-weight: 600;
  white-space: nowrap;
}
.ops-matrix .ops-h-unit,
.pnl-matrix .ops-h-unit {
  font-size: 10px; font-weight: 400;
  text-transform: none; letter-spacing: 0;
}

/* Ячейки по проектам: ok / bad */
.cell-ok { background: #dcfce7 !important; }
.cell-ok .inp-flush { color: #047857; font-weight: 600; }
.cell-bad { background: #fee2e2 !important; }
.cell-bad .inp-flush { color: #b91c1c; font-weight: 600; }

/* Факт из Dodo IS под инпутом таргета в ops-матрице */
.ops-matrix .cell-sub {
  font-size: 10px;
  line-height: 1.2;
  text-align: right;
  margin-top: 1px;
  min-height: 12px;  /* чтобы высоты строк не плясали при пустых фактах */
}

/* Month select в block-head */
.dense-block .month-select {
  padding: 3px 8px; font-size: 12px;
  border: 1px solid var(--border); border-radius: 4px;
  background: white;
}

/* ========== Шаблон статей P&L (импорт из ПланФакт) ========== */
table.tpl-tree {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
}
table.tpl-tree thead th {
  background: #f3f4f6;
  color: var(--text);
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .3px;
  text-align: left;
  padding: 6px 10px;
  border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 1;
  white-space: nowrap;
}
table.tpl-tree tbody td {
  padding: 3px 10px;
  border-bottom: 1px solid var(--border-light);
  vertical-align: middle;
  background: white;
}
table.tpl-tree tbody tr:hover td { background: #fafbfc; }
table.tpl-tree td.tpl-title {
  white-space: nowrap;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
  font-size: 12px;
}
table.tpl-tree td.tpl-code-cell {
  width: 1%;
  white-space: nowrap;
}
table.tpl-tree td.tpl-code-cell select {
  font-size: 11px;
  padding: 1px 4px;
  border: 1px solid var(--border);
  border-radius: 3px;
  background: white;
  color: var(--text);
}
table.tpl-tree td.tpl-path {
  font-size: 11px;
  color: var(--muted);
  max-width: 480px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
table.tpl-tree tr.tpl-calc td { background: #f8f8f8; }
table.tpl-tree tr.tpl-calc td.tpl-title {
  color: var(--muted);
  font-style: italic;
}
table.tpl-tree tr.tpl-section td.tpl-title {
  font-weight: 700;
}
.tpl-warnings {
  padding: 8px 14px;
  background: #fffbea;
  border-bottom: 1px solid #fde68a;
  color: #92400e;
  font-size: 12px;
}
.tpl-warnings ul { margin: 4px 0 0 18px; }
.tpl-stats {
  padding: 8px 14px;
  font-size: 12px;
  color: var(--muted);
  border-bottom: 1px solid var(--border-light);
  background: #fcfcfd;
}
.tpl-stats strong { color: var(--text); font-weight: 600; }

/* ========== Профиль / Интеграции ========== */
.profile-form { display: flex; flex-direction: column; gap: 12px; max-width: 480px; width: 100%; }
.profile-form > label {
  /* > label чтобы перебить общее .controls label из топбар-секции.
     Внутренний input помещаем под текст лейбла, не сбоку. */
  display: flex !important;
  flex-direction: column !important;
  gap: 4px;
  font-size: 12px; font-weight: 500; color: var(--muted);
  width: 100%;
}
.profile-form input:not([type="checkbox"]):not([type="radio"]) {
  width: 100%; box-sizing: border-box;
}
.profile-form input[type="checkbox"], .profile-form input[type="radio"] {
  width: auto; flex: 0 0 auto;
}
/* Чекбокс с подписью внутри .profile-form: чекбокс + текст в одну строку,
 * прижато влево, шрифт как у обычной строки формы. */
.profile-form > label.checkbox-row {
  display: flex !important;
  flex-direction: row !important;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  width: auto;
  font-size: 14px;
  color: var(--text);
  font-weight: 400;
}
.profile-form input[type="password"],
.profile-form input[type="text"] {
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 14px;
  background: white;
}
.profile-form input:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 2px rgba(59,130,246,.15);
}
.profile-msg {
  font-size: 13px;
  padding: 8px 10px;
  border-radius: 6px;
  display: none;
}
.profile-msg.ok {
  display: block;
  background: #ecfdf5; color: #047857;
  border: 1px solid #a7f3d0;
}
.profile-msg.err {
  display: block;
  background: #fef2f2; color: #b91c1c;
  border: 1px solid #fecaca;
}
.profile-row {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px;
  padding: 6px 0;
}
.profile-row code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
}

/* Mobile */
@media (max-width: 800px) {
  .settings-dense { padding: 10px; gap: 10px; }
  .dense-block .block-head { flex-direction: column; align-items: flex-start; }
  .dense-block .block-head .block-inline-ctl { margin-left: 0; }
  .matrix-table .metric-col { min-width: 140px; }
  table.tpl-tree td.tpl-path { display: none; }
}

/* ============ Метрики (KPI с формулами) ============ */
.metrics-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.metrics-table th, .metrics-table td {
  padding: 6px 8px;
  border-bottom: 1px solid var(--border, #e5e7eb);
  vertical-align: middle;
}
.metrics-table th {
  background: var(--bg-soft, #f9fafb);
  text-align: left;
  font-weight: 600;
  color: var(--muted, #6b7280);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.metrics-table td input[type="text"],
.metrics-table td input[type="number"],
.metrics-table td select {
  width: 100%;
  padding: 4px 6px;
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 4px;
  font-size: 13px;
  background: white;
}
.metrics-table .formula-input {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12.5px;
}
.metrics-table .formula-status {
  font-size: 11.5px;
  margin-top: 3px;
  color: var(--muted, #6b7280);
  min-height: 14px;
  line-height: 1.3;
}
.metrics-table .formula-status.ok { color: #047857; }
.metrics-table .formula-status.err { color: #b91c1c; }
.metrics-table .metric-value-cell {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12.5px;
  color: var(--muted, #6b7280);
  text-align: right;
}
.metrics-table .metric-check, .metrics-table .metric-delete {
  padding: 3px 9px;
  font-size: 13px;
}
.btn-danger {
  background: #fef2f2;
  color: #b91c1c;
  border: 1px solid #fecaca;
  border-radius: 4px;
  cursor: pointer;
}
.btn-danger:hover { background: #fee2e2; }

/* ============ Структура: колонка № (line_no) ============ */
.tpl-tree th.tpl-lineno-head { width: 50px; text-align: right; }
.tpl-tree td.tpl-lineno {
  text-align: right;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11.5px;
  color: var(--muted, #6b7280);
}
.tpl-tree td.tpl-lineno code {
  font-size: inherit;
  background: transparent;
  padding: 0;
}

/* ============ Метрики: layout с боковой панелью ============ */
.metrics-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: 12px;
  align-items: start;
}
.metrics-aside .block-head h3 {
  margin: 0;
  font-size: 13px;
  text-transform: uppercase;
  color: var(--muted, #6b7280);
  letter-spacing: 0.03em;
}
.metrics-line-search {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 4px;
  font-size: 13px;
  margin-bottom: 8px;
}
.metrics-line-list {
  max-height: calc(100vh - 280px);
  overflow-y: auto;
  font-size: 12.5px;
}
.metrics-line-list .line-row {
  display: flex;
  gap: 8px;
  padding: 4px 6px;
  border-radius: 3px;
  cursor: pointer;
  border-bottom: 1px solid var(--border-soft, #f3f4f6);
}
.metrics-line-list .line-row:hover {
  background: var(--bg-hover, #f3f4f6);
}
.metrics-line-list .line-row code {
  flex: 0 0 auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11.5px;
  color: var(--accent, #2563eb);
  min-width: 36px;
}
.metrics-line-list .line-title {
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (max-width: 1100px) {
  .metrics-layout { grid-template-columns: 1fr; }
  .metrics-aside { order: -1; }
  .metrics-line-list { max-height: 240px; }
}

/* Заголовок группы в админ-модалке «Проекты юзера» */
.up-group-head {
  background: var(--bg-soft, #f9fafb);
  border-top: 2px solid var(--border, #e5e7eb);
}
.up-group-head td {
  padding: 8px 10px !important;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted, #6b7280);
  text-align: left;
}
.up-group-head td strong {
  color: var(--fg, #111827);
  font-size: 13px;
  text-transform: none;
  letter-spacing: 0;
}
.up-row { background: white; }
/* Иерархия: заголовок группы — без отступа (левее), проекты группы —
   с отступом (правее), как стандартное tree-view. */
.up-row td { text-align: left; }
.up-row td:nth-child(2) { padding-left: 24px; }

/* Модалка «Проекты юзера/ключа»: фиксированный layout колонок,
   text-align явно слева. Без этого ВКЛ-колонка раздувалась до 1/3
   ширины модалки. */
#upTableWrap .dense-table {
  width: 100%;
  table-layout: fixed;
}
#upTableWrap .dense-table th:first-child,
#upTableWrap .dense-table td:first-child {
  width: 56px;
}
#upTableWrap .dense-table th,
#upTableWrap .dense-table tbody td {
  text-align: left;
}
#upTableWrap .dense-table th.cell-center,
#upTableWrap .dense-table tbody td.cell-center {
  text-align: center;
}
/* Перебиваем общий .up-row td:nth-child(2) padding-left — для второй
   колонки именно padding 24px (отступ tree-view) + не растягиваем */
#upTableWrap .dense-table tbody td:nth-child(2) {
  white-space: normal;
  word-break: break-word;
}

/* Sticky-bar «Применить» в сайдбаре главной */
.proj-apply-bar {
  position: sticky;
  bottom: 0;
  background: linear-gradient(to top, white 60%, rgba(255,255,255,0.85));
  padding: 10px 6px 4px;
  margin: 8px -6px -4px;
  border-top: 1px solid var(--border, #e5e7eb);
  display: flex;            /* всегда виден, как у Пульса */
  flex-direction: column;
  gap: 6px;
  z-index: 10;
}
.proj-apply-bar .bar-text {
  font-size: 11.5px;
  color: #b45309;
  text-align: center;
  font-weight: 500;
  visibility: hidden;       /* текст-подсказка только при несохранённых изменениях */
}
.proj-apply-bar.dirty .bar-text { visibility: visible; }
.proj-apply-bar:not(.dirty) .btn-apply { opacity: .55; }
.proj-apply-bar .bar-actions {
  display: flex;
  gap: 6px;
}
.proj-apply-bar button {
  flex: 1;
  font-size: 12px;
  padding: 6px 10px;
}
.proj-apply-bar .btn-apply {
  background: #2563eb;
  color: white;
  border: 1px solid #1d4ed8;
  border-radius: 4px;
  cursor: pointer;
  font-weight: 500;
}
.proj-apply-bar .btn-apply:hover { background: #1d4ed8; }
.proj-apply-bar .btn-cancel {
  background: white;
  color: var(--muted, #6b7280);
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 4px;
  cursor: pointer;
}
