/* ============================================================
   ФУДФЭКТОРИ · Аналитика — стили
   Тема: --hue/--sat (цвет), --bg-blur (фон), --glass-blur (стекло).
   ============================================================ */

/* ---------- Шрифт (офлайн) ---------- */
@font-face { font-family: "Manrope"; font-weight: 400; font-display: swap;
  src: url("../assets/fonts/manrope-cyrillic-400-normal.woff2") format("woff2"),
       url("../assets/fonts/manrope-latin-400-normal.woff2") format("woff2"); }
@font-face { font-family: "Manrope"; font-weight: 600; font-display: swap;
  src: url("../assets/fonts/manrope-cyrillic-600-normal.woff2") format("woff2"),
       url("../assets/fonts/manrope-latin-600-normal.woff2") format("woff2"); }
@font-face { font-family: "Manrope"; font-weight: 800; font-display: swap;
  src: url("../assets/fonts/manrope-cyrillic-800-normal.woff2") format("woff2"),
       url("../assets/fonts/manrope-latin-800-normal.woff2") format("woff2"); }

/* ---------- Токены ---------- */
:root {
  --hue: 205;
  --sat: 70;
  --bg-blur: 14px;
  --glass-blur: 18px;

  --acc: hsl(var(--hue) calc(var(--sat) * 1%) 60%);
  --acc-soft: hsla(var(--hue), calc(var(--sat) * 1%), 60%, .18);
  --acc-line: hsla(var(--hue), calc(var(--sat) * 1%), 70%, .45);

  --ink: hsl(var(--hue) 30% 96%);
  --ink-dim: hsla(var(--hue), 25%, 92%, .62);
  --ink-faint: hsla(var(--hue), 25%, 92%, .38);

  --glass: hsla(var(--hue), 45%, 10%, .42);
  --glass-strong: hsla(var(--hue), 45%, 9%, .72);
  --glass-border: hsla(0, 0%, 100%, .13);
  --glass-shine: hsla(0, 0%, 100%, .10);

  --radius: 18px;
  --radius-s: 12px;
  --shadow: 0 12px 40px hsla(var(--hue), 60%, 4%, .45);
  --topbar-h: 56px;
  font-size: 15px;
}

/* ---------- Светлая тема ---------- */
html[data-theme="light"] {
  --ink: hsl(var(--hue) 45% 9%);
  --ink-dim: hsla(var(--hue), 40%, 14%, .88);
  --ink-faint: hsla(var(--hue), 35%, 20%, .70);
  --glass: hsla(0, 0%, 100%, .62);
  --glass-strong: hsla(0, 0%, 100%, .86);
  --glass-border: hsla(var(--hue), 40%, 30%, .16);
  --glass-shine: hsla(0, 0%, 100%, .55);
  --shadow: 0 12px 34px hsla(var(--hue), 40%, 40%, .18);
}
html[data-theme="light"] body { background: hsl(var(--hue) 30% 94%); }
html[data-theme="light"] .bg-tint {
  background:
    radial-gradient(1200px 600px at 80% -10%, hsla(var(--hue), 60%, 70%, .25), transparent 60%),
    linear-gradient(180deg, hsla(0, 0%, 100%, .55), hsla(var(--hue), 30%, 92%, .72));
}
html[data-theme="light"] .bg-novideo .bg-tint {
  background:
    radial-gradient(1000px 700px at 15% 0%, hsla(var(--hue), 55%, 78%, .55), transparent 55%),
    radial-gradient(900px 600px at 90% 100%, hsla(calc(var(--hue) + 40), 50%, 80%, .5), transparent 55%),
    hsl(var(--hue) 30% 94%);
}
html[data-theme="light"] .tab:hover { background: hsla(var(--hue), 40%, 30%, .07); }
html[data-theme="light"] .icon-btn { background: hsla(var(--hue), 40%, 30%, .06); }
html[data-theme="light"] .mselect-btn,
html[data-theme="light"] .date-input,
html[data-theme="light"] .select,
html[data-theme="light"] .mselect-search input { background: hsla(0, 0%, 100%, .75); }
html[data-theme="light"] .date-input { color-scheme: light; }
html[data-theme="light"] .select option { background: #fff; color: var(--ink); }
html[data-theme="light"] .tbl th { background: hsla(0, 0%, 100%, .92); }
html[data-theme="light"] .tbl th, html[data-theme="light"] .tbl td { border-bottom-color: hsla(var(--hue), 30%, 30%, .12); }
html[data-theme="light"] .tbl tr:hover td { background: hsla(var(--hue), 40%, 50%, .06); }
html[data-theme="light"] input[type="range"] { background: hsla(var(--hue), 30%, 30%, .18); }
html[data-theme="light"] .kpi .kpi-label,
html[data-theme="light"] .panel h3,
html[data-theme="light"] .filter-label,
html[data-theme="light"] .tbl th { color: hsla(var(--hue), 40%, 18%, .78); }
html[data-theme="light"] .copy-hint, html[data-theme="light"] .settings-note { color: hsla(var(--hue), 35%, 22%, .72); }
html[data-theme="light"] .metric-btn { color: hsla(var(--hue), 35%, 20%, .78); }
html[data-theme="light"] .dual-track { background: hsla(var(--hue), 30%, 30%, .18); }

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

body {
  font-family: "Manrope", "Segoe UI", system-ui, sans-serif;
  color: var(--ink);
  min-height: 100vh;
  background: hsl(var(--hue) 45% 7%);
  overflow-x: hidden;
}

/* ---------- Фон: видео ---------- */
.bg { position: fixed; inset: 0; z-index: -1; overflow: hidden; }
.bg video {
  position: absolute; top: 50%; left: 50%;
  min-width: 100%; min-height: 100%;
  transform: translate(-50%, -50%);
  filter: blur(var(--bg-blur));
  object-fit: cover; width: 100%; height: 100%;
}
.bg-tint {
  position: absolute; inset: 0;
  background:
    radial-gradient(1200px 600px at 80% -10%, hsla(var(--hue), 70%, 50%, .12), transparent 60%),
    linear-gradient(180deg, hsla(var(--hue), 50%, 6%, .55), hsla(var(--hue), 50%, 5%, .78));
}
.bg-novideo video { display: none; }
.bg-novideo .bg-tint {
  background:
    radial-gradient(1000px 700px at 15% 0%, hsla(var(--hue), 65%, 35%, .35), transparent 55%),
    radial-gradient(900px 600px at 90% 100%, hsla(calc(var(--hue) + 40), 60%, 30%, .30), transparent 55%),
    hsl(var(--hue) 45% 8%);
}

/* ---------- Стекло (без анимации перелива) ---------- */
.glass, .glass-soft {
  position: relative;
  background: var(--glass);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow), inset 0 1px 0 var(--glass-shine);
  backdrop-filter: blur(var(--glass-blur)) saturate(150%);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(150%);
}
.glass-soft { background: hsla(var(--hue), 40%, 12%, .30); box-shadow: none; }

@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }

/* ---------- Шапка ---------- */
.topbar {
  position: sticky; top: 10px; z-index: 50;
  margin: 10px 14px 0;
  height: var(--topbar-h);
  display: flex; align-items: center; gap: 18px;
  padding: 0 14px;
  border-radius: 16px;
}
.brand { display: flex; align-items: center; gap: 8px; white-space: nowrap; }
/* размеры значка — ниже, в блоке про шестерёнку */
.brand-name { font-weight: 800; letter-spacing: .06em; }

.tabs { display: flex; gap: 4px; margin: 0 auto; overflow-x: auto; scrollbar-width: none; }
.tabs::-webkit-scrollbar { display: none; }
.tab {
  appearance: none; border: 1px solid transparent; background: transparent;
  color: var(--ink-dim); font: inherit; font-weight: 600;
  padding: 8px 14px; border-radius: 12px; cursor: pointer;
  transition: background .18s, color .18s, border-color .18s;
  white-space: nowrap;
}
.tab:hover { color: var(--ink); background: hsla(0,0%,100%,.06); }
.tab.active {
  color: var(--ink);
  background: var(--acc-soft);
  border-color: var(--acc-line);
  box-shadow: inset 0 1px 0 hsla(0,0%,100%,.12);
}
.topbar-right { display: flex; align-items: center; gap: 10px; }
.hint { color: var(--ink-faint); font-size: .72rem; border: 1px solid var(--glass-border); border-radius: 8px; padding: 3px 8px; }

.icon-btn {
  appearance: none; border: 1px solid var(--glass-border); background: hsla(0,0%,100%,.05);
  color: var(--ink); width: 34px; height: 34px; border-radius: 10px;
  font-size: 1rem; cursor: pointer; transition: background .18s;
}
.icon-btn:hover { background: hsla(0,0%,100%,.12); }

/* ---------- Фреймы ---------- */
#frames { padding: 16px 14px 40px; max-width: 1500px; margin: 0 auto; }
.frame > * { min-width: 0; }
.frame { display: none; animation: fadeUp .25s ease; }
.frame.active { display: block; }
@keyframes fadeUp { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

.loading { display: flex; flex-direction: column; align-items: center; gap: 14px; padding: 80px 0; color: var(--ink-dim); }
.spinner {
  width: 34px; height: 34px; border-radius: 50%;
  border: 3px solid var(--acc-soft); border-top-color: var(--acc);
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.stub { padding: 60px 30px; text-align: center; color: var(--ink-dim); }
.stub h2 { margin: 0 0 10px; color: var(--ink); }

/* ---------- Кнопки, сегменты ---------- */
.btn {
  appearance: none; font: inherit; font-weight: 600; cursor: pointer;
  color: var(--ink); background: var(--acc-soft);
  border: 1px solid var(--acc-line); border-radius: var(--radius-s);
  padding: 8px 16px; transition: background .18s;
}
.btn:hover { background: hsla(var(--hue), calc(var(--sat) * 1%), 60%, .30); }
.btn.ghost { background: transparent; border-color: var(--glass-border); color: var(--ink-dim); }
.btn.ghost:hover { color: var(--ink); background: hsla(0,0%,100%,.06); }

.seg { display: inline-flex; border: 1px solid var(--glass-border); border-radius: var(--radius-s); overflow: hidden; }
.seg button {
  appearance: none; border: 0; background: transparent; color: var(--ink-dim);
  font: inherit; font-weight: 600; padding: 7px 12px; cursor: pointer;
  transition: background .18s, color .18s;
}
.seg button + button { border-left: 1px solid var(--glass-border); }
.seg button.active { background: var(--acc-soft); color: var(--ink); }

.mini-seg { display: inline-flex; border: 1px solid var(--glass-border); border-radius: 9px; overflow: hidden; }
.mini-seg button {
  appearance: none; border: 0; background: transparent; color: var(--ink-faint);
  font: inherit; font-size: .85rem; line-height: 1; padding: 6px 10px; cursor: pointer;
  transition: background .18s, color .18s;
}
.mini-seg button + button { border-left: 1px solid var(--glass-border); }
.mini-seg button.active { background: var(--acc-soft); color: var(--ink); }

/* ---------- Панель настроек ---------- */
.settings {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 90;
  width: min(340px, 92vw);
  border-radius: 0; border-width: 0 0 0 1px;
  background: var(--glass-strong);
  padding: 20px;
  transform: translateX(105%);
  transition: transform .28s cubic-bezier(.2,.8,.2,1);
  overflow-y: auto;
}
.settings.open { transform: none; }
.settings-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.settings-head h2 { margin: 0; font-size: 1.1rem; }
.settings-group { margin: 20px 0; }
.settings-label { display: block; color: var(--ink-dim); font-size: .85rem; margin-bottom: 8px; }
.settings-label b { color: var(--ink); }
.settings-note { color: var(--ink-faint); font-size: .75rem; margin-top: 6px; }

.scrim { position: fixed; inset: 0; z-index: 80; background: hsla(0,0%,0%,.35); opacity: 0; pointer-events: none; transition: opacity .25s; }
.scrim.show { opacity: 1; pointer-events: auto; }

/* ---------- Ползунки ---------- */
input[type="range"] {
  width: 100%; appearance: none; height: 6px; border-radius: 3px;
  background: hsla(0,0%,100%,.15); outline: none;
}
input[type="range"]::-webkit-slider-runnable-track { height: 6px; border-radius: 3px; background: transparent; }
input[type="range"]::-webkit-slider-thumb {
  appearance: none; width: 18px; height: 18px; border-radius: 50%;
  margin-top: -6px; /* центр кругляша ровно на линии */
  background: var(--acc); border: 2px solid hsla(0,0%,100%,.8);
  box-shadow: 0 2px 8px hsla(0,0%,0%,.4); cursor: pointer;
}
input[type="range"]::-moz-range-track { height: 6px; border-radius: 3px; background: transparent; }
input[type="range"]::-moz-range-thumb {
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--acc); border: 2px solid hsla(0,0%,100%,.8); cursor: pointer;
}

/* ---------- Сетка раздела ---------- */
.panel { padding: 16px 18px; margin-bottom: 14px; min-width: 0; overflow: hidden; }
.panel h3 { margin: 0 0 12px; font-size: .95rem; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-dim); }
.panel-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.panel-head h3 { margin-bottom: 12px; }

.grid-kpi { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; margin-bottom: 14px; }
.grid-kpi > * { min-width: 0; }
.kpi .kpi-value { overflow-wrap: anywhere; }
.kpi { padding: 14px 18px; }
.kpi .kpi-label { color: var(--ink-faint); font-size: .75rem; letter-spacing: .08em; text-transform: uppercase; }
.kpi .kpi-value { font-size: 1.7rem; font-weight: 800; margin-top: 4px; font-variant-numeric: tabular-nums; }
.kpi .kpi-sub { color: var(--ink-dim); font-size: .78rem; margin-top: 2px; }

/* minmax(0,1fr) — иначе широкие таблицы/подписи распирают колонку
   и сетка перестаёт сжиматься при сужении окна */
.grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.grid-2 > * { min-width: 0; }
@media (max-width: 1000px) { .grid-2 { grid-template-columns: minmax(0, 1fr); } }

.chart-wrap { position: relative; height: 320px; min-width: 0; }
.chart-wrap.tall { height: 420px; }

/* ---------- Панель фильтров ---------- */
/* Панель фильтров — сетка из колонок одинаковой ширины.
 *
 * Раньше это был flex, где каждый блок тянулся по-своему: в «Заказах»
 * пять списков выстраивались в ряд и «Сбросить» уезжала на вторую
 * строку, в «Выпуске» единственный список прижимался к низу, а между
 * периодом и группировкой зияла дыра. В сетке все колонки одной ширины
 * и выровнены по верху, поэтому набор фильтров может быть любым.
 *
 * auto-fill, а не auto-fit: пустые колонки в конце строки должны
 * остаться пустыми, иначе блок периода растянулся бы на пол-экрана.
 */
/* Панель фильтров.
 *
 * Раскладка «по содержимому», а не сеткой равных колонок: у сетки блок
 * периода занимал две колонки, но заполнял их наполовину — отсюда были
 * пустоты между периодом и группировкой. Теперь каждый блок занимает
 * ровно свою ширину, а свободное место забирают выпадающие списки
 * (им ширина всегда на пользу: названия клиентов длинные).
 *
 * Порядок и внутреннее устройство блоков от ширины окна не зависят:
 * меняется только момент переноса на вторую строку.
 */
.filters {
  display: flex; flex-wrap: wrap;
  gap: 10px 14px; align-items: flex-start;
  padding: 12px 16px; margin-bottom: 14px;
  /* backdrop-filter создаёт контексты наложения, поэтому фильтрам нужен
     явный z-index — иначе выпадающие списки уходят под нижние панели */
  position: relative; z-index: 40;
}
.filter-block { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.filter-block.narrow { flex: 0 0 auto; min-width: 0; }
/* группировка и «Сбросить» — по ширине содержимого, а не во всю колонку */
.filter-block.narrow > .seg, .filter-block.narrow > .btn { align-self: start; }

/* два списка в одну колонку — по высоте это ровно блок периода.
   Растут, забирая свободное место, но не больше разумного: на широком
   мониторе список во весь экран выглядит нелепо. */
.filter-col { display: flex; flex-direction: column; gap: 8px; min-width: 0; flex: 1 1 200px; max-width: 460px; }
.filter-col .filter-block { min-width: 0; }

/* «Сбросить» прижата к правому краю: остаток ширины собирается в одном
   месте и читается как отступ, а не как дыра посреди панели */
.filters .reset-col { margin-left: auto; }

.period-col { flex: 0 0 auto; }

/* Строки периода жёстко одна под другой: раньше при некоторых ширинах
   номера недель вставали справа от календариков, и панель «прыгала». */
.period-controls { display: block; }
.date-row { margin-top: 0; flex-wrap: nowrap; }
.week-row { margin-top: 6px; flex-wrap: nowrap; }
/* календарики должны уметь сжиматься: в узкой колонке два поля рядом
   не помещаются, и без этого они вылезали за край панели */
.date-input { min-width: 0; }
.filter-label { color: var(--ink-faint); font-size: .72rem; letter-spacing: .08em; text-transform: uppercase; }

/* мультиселект с поиском */
.mselect { position: relative; }
.mselect-btn {
  width: 100%; text-align: left; appearance: none; cursor: pointer;
  font: inherit; color: var(--ink);
  background: hsla(0,0%,100%,.06); border: 1px solid var(--glass-border);
  border-radius: var(--radius-s); padding: 8px 32px 8px 12px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mselect-btn::after { content: "▾"; position: absolute; right: 12px; color: var(--ink-faint); }
.mselect-pop {
  position: absolute; z-index: 60; top: calc(100% + 6px); left: 0; right: 0;
  max-height: 320px; display: none; flex-direction: column;
  /* почти непрозрачный фон: сквозь список не должно просвечивать содержимое */
  background: hsl(var(--hue) 45% 11%);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-s); box-shadow: var(--shadow);
  backdrop-filter: blur(var(--glass-blur));
}
html[data-theme="light"] .mselect-pop { background: hsl(var(--hue) 25% 98%); }
.mselect.open .mselect-pop { display: flex; }
.mselect-search { padding: 8px; border-bottom: 1px solid var(--glass-border); }
.mselect-search input {
  width: 100%; font: inherit; color: var(--ink);
  background: hsla(0,0%,100%,.07); border: 1px solid var(--glass-border);
  border-radius: 8px; padding: 6px 10px; outline: none;
}
.mselect-list { overflow-y: auto; padding: 4px; }
.mselect-item {
  display: flex; gap: 8px; align-items: center; cursor: pointer;
  padding: 6px 8px; border-radius: 8px; font-size: .88rem;
}
.mselect-item:hover { background: hsla(0,0%,100%,.07); }
.mselect-item input { accent-color: var(--acc); }
.mselect-foot { display: flex; gap: 6px; padding: 8px; border-top: 1px solid var(--glass-border); }
.mselect-foot .btn { padding: 5px 10px; font-size: .8rem; }

/* двойной ползунок дат + календари */
/* Ползунок периода убран в v9: он растягивал панель фильтров, а попасть
   им в нужный день на длинной шкале всё равно было нельзя. Остались
   календарики и номера недель — см. UIC.periodPicker. */
.date-row { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.date-row span { color: var(--ink-faint); font-size: .8rem; }
.date-input {
  font: inherit; font-size: .82rem; color: var(--ink);
  background: hsla(0,0%,100%,.06); border: 1px solid var(--glass-border);
  border-radius: 8px; padding: 4px 8px; outline: none;
  font-variant-numeric: tabular-nums; cursor: pointer;
  color-scheme: dark; /* тёмный календарь браузера */
}
.date-input:focus { border-color: var(--acc-line); }

/* ---------- Таблицы ---------- */
.tbl { width: 100%; border-collapse: collapse; font-size: .86rem; }
.tbl th, .tbl td { padding: 7px 10px; text-align: left; border-bottom: 1px solid hsla(0,0%,100%,.07); }
.tbl th { color: var(--ink-faint); font-weight: 600; font-size: .74rem; letter-spacing: .06em; text-transform: uppercase; position: sticky; top: 0; background: hsla(var(--hue), 45%, 10%, .92); }
.tbl td.num, .tbl th.num { text-align: right; font-variant-numeric: tabular-nums; }
.tbl tr:hover td { background: hsla(0,0%,100%,.04); }
.tbl-scroll { max-height: 340px; overflow: auto; border-radius: var(--radius-s); max-width: 100%; }
.tbl { min-width: 480px; } /* горизонтальная прокрутка вместо ломки вёрстки */

/* Полосы прокрутки: тонкие, полупрозрачные, в тон интерфейсу.
   Firefox — через scrollbar-*, WebKit — через ::-webkit-scrollbar. */
.tbl-scroll, .mselect-list, .settings, .newsfeed-body, #frames {
  scrollbar-width: thin;
  scrollbar-color: hsla(var(--hue), calc(var(--sat) * 1%), 60%, .45) transparent;
}
.tbl-scroll::-webkit-scrollbar,
.mselect-list::-webkit-scrollbar,
.settings::-webkit-scrollbar,
.newsfeed-body::-webkit-scrollbar { width: 10px; height: 10px; }
.tbl-scroll::-webkit-scrollbar-track,
.mselect-list::-webkit-scrollbar-track,
.settings::-webkit-scrollbar-track,
.newsfeed-body::-webkit-scrollbar-track { background: transparent; }
.tbl-scroll::-webkit-scrollbar-thumb,
.mselect-list::-webkit-scrollbar-thumb,
.settings::-webkit-scrollbar-thumb,
.newsfeed-body::-webkit-scrollbar-thumb {
  border-radius: 999px;
  background: linear-gradient(180deg,
    hsla(var(--hue), calc(var(--sat) * 1%), 68%, .55),
    hsla(var(--hue), calc(var(--sat) * 1%), 52%, .40));
  border: 3px solid transparent;   /* делает «ползунок» уже дорожки */
  background-clip: padding-box;
}
.tbl-scroll::-webkit-scrollbar-thumb:hover,
.mselect-list::-webkit-scrollbar-thumb:hover,
.settings::-webkit-scrollbar-thumb:hover,
.newsfeed-body::-webkit-scrollbar-thumb:hover {
  background: linear-gradient(180deg,
    hsla(var(--hue), calc(var(--sat) * 1%), 74%, .8),
    hsla(var(--hue), calc(var(--sat) * 1%), 58%, .65));
  background-clip: padding-box;
}
.tbl-scroll::-webkit-scrollbar-corner { background: transparent; }

/* ---------- Dropzone ---------- */
.dropzone {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  padding: 50px 24px; text-align: center;
  border: 1.5px dashed var(--glass-border);
}
.dropzone.drag { border-color: var(--acc); background: var(--acc-soft); }
.dz-icon { font-size: 2rem; }
.dz-title { font-weight: 800; font-size: 1.05rem; }
.dz-text { color: var(--ink-dim); max-width: 560px; }
.dz-text.dim { color: var(--ink-faint); }
.dz-text.small { font-size: .78rem; }

.status-line { color: var(--ink-faint); font-size: .76rem; margin: 4px 4px 12px; }
.copy-hint { color: var(--ink-faint); font-size: .72rem; margin-top: 8px; }

/* ---------- Select ---------- */
.select {
  width: 100%; font: inherit; color: var(--ink); cursor: pointer;
  background: hsla(0,0%,100%,.06); border: 1px solid var(--glass-border);
  border-radius: var(--radius-s); padding: 8px 12px; outline: none;
}
.select option { background: hsl(var(--hue) 45% 12%); color: var(--ink); }

/* ---------- Тост ---------- */
.toast {
  position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%) translateY(20px);
  z-index: 100; max-width: min(90vw, 480px);
  background: var(--glass-strong); border: 1px solid var(--acc-line);
  border-radius: var(--radius-s); padding: 10px 18px;
  color: var(--ink); font-size: .88rem;
  box-shadow: var(--shadow);
  backdrop-filter: blur(var(--glass-blur));
  opacity: 0; pointer-events: none;
  transition: opacity .25s, transform .25s;
}
.toast.show { opacity: 1; transform: translateX(-50%); }

/* ---------- Интерактивная подсказка диаграмм ---------- */
/* Своя подсказка вместо встроенной: в неё можно положить кнопку
   «посмотреть по неделям/дням» и кликнуть по ней мышью. */
.chart-tip {
  position: fixed; z-index: 95; pointer-events: none;
  min-width: 190px; max-width: 320px;
  background: var(--glass-strong);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-s);
  box-shadow: var(--shadow);
  backdrop-filter: blur(var(--glass-blur));
  padding: 10px 12px;
  opacity: 0; transition: opacity .15s;
  font-size: .84rem;
}
.chart-tip.show { opacity: 1; }
.chart-tip .tip-title { font-weight: 800; margin-bottom: 6px; }
.chart-tip .tip-row { display: flex; justify-content: space-between; gap: 14px; padding: 1px 0; color: var(--ink-dim); }
.chart-tip .tip-row b { color: var(--ink); font-variant-numeric: tabular-nums; font-weight: 600; }
.chart-tip .tip-row.lead b { font-size: 1.05rem; font-weight: 800; }

/* ---------- Переключатель метрик (кнопки вкл/выкл) ---------- */
.metric-seg { display: inline-flex; gap: 6px; flex-wrap: wrap; }
.metric-btn {
  appearance: none; cursor: pointer; font: inherit; font-size: .78rem; font-weight: 600;
  color: var(--ink-faint); background: transparent;
  border: 1px solid var(--glass-border); border-radius: 9px; padding: 5px 10px;
  display: inline-flex; align-items: center; gap: 6px;
  transition: background .18s, color .18s, border-color .18s;
}
.metric-btn .dot { width: 9px; height: 9px; border-radius: 50%; background: currentColor; opacity: .5; }
.metric-btn.on { color: var(--ink); border-color: var(--acc-line); background: var(--acc-soft); }
.metric-btn.on .dot { opacity: 1; }

/* ---------- Тема: иконки в настройках ---------- */
.theme-seg { display: inline-flex; border: 1px solid var(--glass-border); border-radius: var(--radius-s); overflow: hidden; }
.theme-seg button {
  appearance: none; border: 0; background: transparent; color: var(--ink-dim);
  font: inherit; font-size: 1rem; padding: 7px 18px; cursor: pointer;
  transition: background .18s, color .18s;
}
.theme-seg button + button { border-left: 1px solid var(--glass-border); }
.theme-seg button.active { background: var(--acc-soft); color: var(--ink); }

/* ---------- Пара графиков: основной (80%) + детальный (20%) ---------- */
.trend-row { display: flex; gap: 14px; align-items: stretch; }
.trend-row > .trend-main { flex: 0 0 calc(70% - 7px); min-width: 0; }
.trend-row > .trend-side { flex: 1 1 auto; min-width: 0; }
.trend-side .chart-wrap { height: 320px; }
.side-empty { display: flex; align-items: center; justify-content: center; height: 320px; text-align: center; color: var(--ink-faint); font-size: .82rem; padding: 0 8px; }
@media (max-width: 1100px) {
  .trend-row { flex-direction: column; }
  .trend-row > .trend-main, .trend-row > .trend-side { flex: 1 1 auto; }
}

/* ---------- Адаптив ---------- */
@media (max-width: 900px) {
  #frames { padding: 12px 10px 32px; }
  .panel { padding: 14px 12px; }
  .grid-kpi { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
}

@media (max-width: 760px) {
  :root { --topbar-h: auto; }
  .topbar { flex-wrap: wrap; padding: 10px 12px; gap: 8px; height: auto; margin: 8px 10px 0; }
  .hint { display: none; }
  .tabs { order: 3; width: 100%; margin: 0; }
  .grid-kpi { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .kpi { padding: 12px 14px; }
  .kpi .kpi-value { font-size: 1.35rem; }
  .filters { gap: 10px; }
  .filter-col { max-width: none; flex: 1 1 100%; }
  .filter-block, .filter-block.narrow { min-width: 0; width: 100%; }
  .filter-block.narrow .seg, .filter-block.narrow .btn { width: 100%; }
  .seg { display: flex; }
  .seg button { flex: 1; }
  .chart-wrap { height: 260px; }
  .chart-wrap.tall { height: 360px; }
  .panel-head { align-items: flex-start; }
  .metric-seg { width: 100%; }
  .settings { width: 100%; }
}

@media (max-width: 460px) {
  .grid-kpi { grid-template-columns: minmax(0, 1fr); }
  .brand-name { font-size: .95rem; }
  .tab { padding: 7px 10px; font-size: .88rem; }
}

/* ============================================================
   Дополнения: обратная связь, диалоги, срезы, мобильные правки
   ============================================================ */

/* ---------- Разделы в разработке ---------- */
/* Кнопка остаётся кликабельной, но видно, что раздел ещё не наполнен. */
.tab.dev { opacity: .45; }
.tab.dev:hover { opacity: .75; }
.tab.dev.active { opacity: 1; }

/* ---------- Значки-кнопки ---------- */
.icon-btn { display: inline-flex; align-items: center; justify-content: center; }
.icon-btn .ic { display: block; }
.user-box { display: flex; align-items: center; gap: 8px; }

/* ---------- Диалог подтверждения ---------- */
.modal-scrim {
  position: fixed; inset: 0; z-index: 120;
  display: flex; align-items: center; justify-content: center;
  background: hsla(0,0%,0%,.45);
  opacity: 0; transition: opacity .18s;
}
.modal-scrim.show { opacity: 1; }
.modal {
  min-width: min(320px, 90vw); max-width: min(460px, 92vw);
  padding: 22px 24px;
  background: var(--glass-strong);
  transform: translateY(8px); transition: transform .18s;
}
.modal-scrim.show .modal { transform: none; }
.modal-text { font-size: 1.05rem; font-weight: 600; white-space: pre-line; }
.modal-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 18px; }
.modal-actions .btn { min-width: 88px; }

/* ---------- Подсказка диаграмм: черта и примечание ---------- */
.chart-tip .tip-sep { height: 1px; background: var(--glass-border); margin: 7px 0 6px; }
.chart-tip .tip-note { color: var(--ink-faint); font-size: .76rem; margin-top: 6px; }
.chart-tip .tip-row.dim span, .chart-tip .tip-row.dim b { color: var(--ink-faint); font-weight: 600; }
/* на телефоне подсказка может быть шире, но не шире экрана */
.chart-tip { max-width: min(460px, calc(100vw - 16px)); }

/* ---------- Календарики: интервал по номерам недель ---------- */
.date-row { flex-wrap: wrap; }
.wk-sep { flex: 1 1 auto; min-width: 4px; }
.wk-label { color: var(--ink-faint); font-size: .72rem; letter-spacing: .06em; text-transform: uppercase; }
select.date-input.wk { padding: 4px 4px; min-width: 58px; cursor: pointer; }
select.date-input.wk option { background: hsl(var(--hue) 45% 12%); color: var(--ink); }
html[data-theme="light"] select.date-input.wk option { background: #fff; }

/* ---------- Круговая диаграмма: своя легенда со значениями ---------- */
.pie-row { display: flex; gap: 12px; align-items: stretch; min-width: 0; }
.pie-row > .chart-wrap { flex: 1 1 auto; min-width: 0; }
.pie-legend {
  flex: 0 0 42%; max-width: 260px; overflow-y: auto; max-height: 420px;
  display: flex; flex-direction: column; gap: 8px; padding-right: 4px;
}
.pie-legend-item { display: flex; gap: 8px; align-items: flex-start; cursor: default; }
.pie-legend[id="tsLegend"] .pie-legend-item { cursor: pointer; }
.pie-legend-item.on .pie-name { color: var(--acc); }
.pie-dot { width: 10px; height: 10px; border-radius: 3px; margin-top: 4px; flex: 0 0 auto; }
.pie-legend-body { display: flex; flex-direction: column; min-width: 0; }
.pie-name { font-size: .82rem; font-weight: 600; overflow-wrap: anywhere; }
.pie-val { font-size: .76rem; color: var(--ink-dim); font-variant-numeric: tabular-nums; }

/* ---------- Галочка в шапке панели ---------- */
.head-tools { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.chk {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  font-size: .78rem; font-weight: 600; color: var(--ink-dim);
  border: 1px solid var(--glass-border); border-radius: 9px; padding: 4px 10px;
}
.chk input { accent-color: var(--acc); margin: 0; }
.chk:hover { color: var(--ink); }

/* ---------- Обратная связь и заметки ---------- */
.fb-input {
  width: 100%; font: inherit; font-size: .92rem; color: var(--ink);
  background: hsla(0,0%,100%,.06); border: 1px solid var(--glass-border);
  border-radius: var(--radius-s); padding: 10px 12px; outline: none; resize: vertical;
}
.fb-input:focus { border-color: var(--acc-line); }
html[data-theme="light"] .fb-input { background: hsla(0,0%,100%,.75); }
.fb-form-actions { display: flex; align-items: center; gap: 12px; margin-top: 10px; flex-wrap: wrap; }
.fb-form-actions .copy-hint { margin-top: 0; }

.fb-item, .note-item {
  border: 1px solid var(--glass-border); border-radius: var(--radius-s);
  padding: 12px 14px; margin-bottom: 10px; background: hsla(0,0%,100%,.03);
}
html[data-theme="light"] .fb-item, html[data-theme="light"] .note-item { background: hsla(0,0%,100%,.45); }
.fb-head, .note-head {
  display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap;
  font-size: .76rem; color: var(--ink-faint); margin-bottom: 6px;
}
.fb-author { font-weight: 700; color: var(--ink-dim); }
.fb-date, .note-date { font-variant-numeric: tabular-nums; }
.note-author { margin-left: auto; }
.fb-text, .note-text { font-size: .92rem; overflow-wrap: anywhere; }
.fb-reply {
  margin-top: 8px; padding-left: 12px; border-left: 2px solid var(--acc-line);
  font-style: italic; font-size: .88rem; color: var(--ink-dim); overflow-wrap: anywhere;
}
.fb-reply-mark { font-style: normal; font-weight: 700; color: var(--ink-faint); font-size: .76rem; }
.fb-actions { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.btn.small { padding: 4px 10px; font-size: .78rem; }
.note-item.pinned { border-color: var(--acc-line); background: var(--acc-soft); }

/* ---------- Админка: выгрузки ---------- */
/* Подзаголовки папок были почти не видны — читались как «серая пыль». */
.data-folder h4 { font-size: 1rem; font-weight: 800; color: var(--ink); letter-spacing: .02em; }
.data-folder .data-dir {
  font-weight: 600; font-size: .86rem;
  color: var(--ink-dim); font-variant-numeric: tabular-nums;
}
.data-note { color: var(--ink-dim); font-size: .78rem; margin: 0 0 8px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.data-note b { color: var(--ink); }

/* Одинаковая ширина столбцов во всех папках */
.data-tbl { table-layout: fixed; min-width: 620px; }
.data-tbl col.c-name { width: 44%; }
.data-tbl col.c-when { width: 16%; }
.data-tbl col.c-size { width: 10%; }
.data-tbl col.c-act  { width: 30%; }
.data-tbl td { overflow-wrap: anywhere; }
.data-tbl .row-act { display: flex; gap: 6px; justify-content: flex-end; flex-wrap: wrap; }
.data-tbl .row-act .btn { white-space: nowrap; text-decoration: none; }
.data-tbl tr.used td { background: hsla(140, 50%, 45%, .07); }

/* ---------- Мобильные правки ---------- */
@media (max-width: 900px) {
  .pie-row { flex-direction: column; }
  .pie-legend { flex: 1 1 auto; max-width: none; max-height: none; }
}
@media (max-width: 760px) {
  .date-row .wk-sep { display: none; }
  .date-row { gap: 6px; }
  .modal-actions .btn { flex: 1; }
  .fb-actions .btn { flex: 1 1 auto; }
}

/* ============================================================
   Дополнения v5: плотные фильтры, шапка, карточки главной
   ============================================================ */

/* ---------- Шапка: город под названием ---------- */
/* «ПОДОЛЬСК» выровнен по правому краю слова «ФУДФЭКТОРИ»: колонка
   выстроена по правому краю, поэтому подпись останется на месте, даже
   если название когда-нибудь поменяется. */
.brand-text { display: flex; flex-direction: column; align-items: flex-end; line-height: 1.05; }
.brand-city {
  font-size: .62rem; font-weight: 700; letter-spacing: .18em;
  color: var(--ink-faint); margin-top: 2px;
}

/* ---------- Плотная панель фильтров ---------- */
/* Плотный вариант (все разделы с фильтрами). Отличается от базового
   только размерами: раскладку задаёт сетка выше. */
.filters.compact { gap: 10px 14px; padding: 12px 16px; }
.filters.compact .filter-block { gap: 4px; }
.filters.compact .filter-label { font-size: .68rem; }

/* группировка столбиком — три коротких кнопки вместо широкой полосы,
   которая не помещалась в колонку сетки */
.filters.compact .seg { flex-direction: column; }
/* три кнопки столбиком — компактнее по высоте, чтобы блок группировки
   не был выше блока периода */
.filters.compact .seg button { text-align: center; padding: 2px 14px; font-size: .78rem; line-height: 1.5; }
.filters.compact .seg button + button {
  border-left: none;
  border-top: 1px solid var(--glass-border);
}

.week-row { display: flex; align-items: center; gap: 8px; }
.week-row span { color: var(--ink-faint); font-size: .8rem; }
.wk-label { text-transform: uppercase; letter-spacing: .06em; font-size: .72rem; }

/* ---------- Карточки главной: период отдельной строкой ---------- */
.kpi-big .kpi-period {
  margin-top: 6px; padding-top: 6px;
  border-top: 1px solid var(--glass-border);
  color: var(--ink-dim); font-size: .78rem; font-variant-numeric: tabular-nums;
}

/* ---------- «Скопировано» после клика по столбику ---------- */
.copy-flash {
  position: fixed; z-index: 130; pointer-events: none;
  padding: 6px 12px; border-radius: 10px;
  background: var(--glass-strong); border: 1px solid var(--acc-line);
  color: var(--ink); font-size: .8rem; font-weight: 700;
  opacity: 0; transform: translateY(4px);
  transition: opacity .18s ease-out, transform .18s ease-out;
}
.copy-flash.show { opacity: 1; transform: none; }
.copy-flash.fade { opacity: 0; transform: translateY(-10px); transition: opacity 1.1s ease-in, transform 1.1s ease-in; }


@media (max-width: 760px) {
  .filters.compact .seg { flex-direction: row; }
  .filters.compact .seg button + button { border-left: 1px solid var(--glass-border); border-top: none; }
  .filters.compact .seg button { flex: 1; }
}

/* ============================================================
   Индикатор загрузки: логотип с вращающейся шестерёнкой
   ============================================================ */

.ff-loader {
  display: flex; flex-direction: column; align-items: center;
  gap: 14px; padding: 36px 12px; text-align: center;
}

/* Пропорции взяты у самих картинок (1217×1432): так слои совпадают
   пиксель в пиксель при любом размере. */
.ff-loader-art { position: relative; width: 132px; aspect-ratio: 1217 / 1432; }
.ff-loader-art img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: contain;
  /* картинки белые — на светлой теме их не было бы видно */
  filter: none;
}
html[data-theme="light"] .ff-loader-art img { filter: invert(1) brightness(.55); }

/* Маска на НЕПОДВИЖНОЙ обёртке: видна только часть ниже 51% высоты.
   Если повесить её на саму шестерёнку, маска вращалась бы вместе
   с картинкой и срезала бы каждый раз другой её кусок. */
.ff-loader-gear-wrap {
  position: absolute; inset: 0;
  clip-path: inset(51% 0 0 0);
  -webkit-clip-path: inset(51% 0 0 0);
}

/* Центр вращения — центр самой шестерёнки, а не картинки:
   по прозрачным полям он смещён вверх на десятую долю процента. */
.ff-loader-gear {
  transform-origin: 50% 49.9%;
  animation: ff-gear-spin 4.5s linear infinite;
}

@keyframes ff-gear-spin { to { transform: rotate(360deg); } }

.ff-loader-text { color: var(--ink-dim); font-size: .9rem; }

/* Мелкий вариант — для панелей админки, где загрузка занимает мгновение */
.ff-loader.small { padding: 22px 8px; gap: 8px; }
.ff-loader.small .ff-loader-art { width: 66px; }
.ff-loader.small .ff-loader-text { font-size: .8rem; }

/* Уважаем системную настройку «меньше движения»: шестерёнка не мигает,
   а просто крутится медленно — совсем без движения непонятно, идёт ли
   загрузка. */
@media (prefers-reduced-motion: reduce) {
  .ff-loader-gear { animation-duration: 14s; }
}

@media (max-width: 760px) {
  .ff-loader-art { width: 104px; }
  .ff-loader { padding: 26px 10px; }
}

/* Строка «с чем сравнивали» в карточке главной. Тише периода: это
   пояснение к стрелке, а не самостоятельный показатель. */
.kpi-big .kpi-base {
  margin-top: 3px;
  color: var(--ink-faint);
  font-size: .76rem;
  font-variant-numeric: tabular-nums;
}
.kpi-big .kpi-base b { color: var(--ink-dim); font-weight: 700; }

/* ============================================================
   Дата и время в шапке
   ============================================================ */

.clock {
  display: flex; flex-direction: column; justify-content: center;
  line-height: 1.15; white-space: nowrap;
  padding-left: 14px;
  /* разделитель вместо отдельного элемента: одна строка вместо лишнего span */
  border-left: 1px solid var(--glass-border);
  font-variant-numeric: tabular-nums;
}

.clock-top { display: flex; align-items: baseline; gap: 6px; }

.clock-label {
  color: var(--ink-faint); font-size: .66rem;
  letter-spacing: .08em; text-transform: uppercase;
}

.clock-day {
  color: var(--ink); font-size: .72rem; font-weight: 800; letter-spacing: .1em;
}

.clock-when { color: var(--ink-dim); font-size: .82rem; font-weight: 700; }

@media (max-width: 1100px) {
  /* «сегодня» уходит первым: подпись очевидна и без него */
  .clock-label { display: none; }
}

@media (max-width: 760px) {
  /* На телефоне часы становятся одной строкой и встают сразу за логотипом.
     ЕСЛИ ЧАСЫ НА ТЕЛЕФОНЕ НЕ НУЖНЫ — раскомментируйте строку ниже,
     больше ничего менять не потребуется:
     .clock { display: none; } */
  .clock { padding-left: 10px; }
  .clock-line { display: flex; align-items: baseline; gap: 6px; }
  .clock-day { font-size: .68rem; }
  .clock-when { font-size: .74rem; font-weight: 600; }
}

/* ============================================================
   Шестерёнка в шапке, значок обратной связи, настройки
   ============================================================ */

/* Значок-шестерёнка вместо снежинки. Вращение задаёт brandmark.js —
   в css только начальное состояние, чтобы значок не «прыгал» до
   загрузки скрипта. */
/* Значок в шапке — та же иконка загрузки: неподвижный логотип, под ним
   вращается шестерёнка, видимая только ниже маски. Проценты взяты из
   самих картинок (обрезаны по общей рамке, поэтому слои совпадают):
   центр шестерёнки 52,1% / 55,1%, край маски 56,4%.
   Вращение задаёт brandmark.js — здесь только исходное состояние. */
.brand-mark {
  position: relative; flex: none;
  width: 45px; height: 46px;
}
.brand-mark img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.brand-gear-wrap {
  position: absolute; inset: 0;
  clip-path: inset(56.4% 0 0 0);
  -webkit-clip-path: inset(56.4% 0 0 0);
}
.brand-gear {
  transform-origin: 52.1% 55.1%;
  will-change: transform;
  user-select: none; -webkit-user-drag: none;
}
html[data-theme="light"] .brand-mark img { filter: invert(1) brightness(.45); }

/* Непрочитанные комментарии: мягкое мерцание, а не резкое моргание —
   значок в шапке видно постоянно, и агрессивная анимация утомляет. */
.icon-btn.alert { position: relative; color: var(--acc); border-color: var(--acc-line); }
.icon-btn.alert { animation: fb-pulse 1.8s ease-in-out infinite; }
@keyframes fb-pulse {
  0%, 100% { box-shadow: 0 0 0 0 hsla(0,0%,100%,0); background: hsla(0,0%,100%,.05); }
  50% { box-shadow: 0 0 0 4px var(--acc-soft); background: var(--acc-soft); }
}
@media (prefers-reduced-motion: reduce) {
  .icon-btn.alert { animation: none; background: var(--acc-soft); }
}

.icon-btn .badge {
  position: absolute; top: -5px; right: -5px;
  min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: 8px;
  background: var(--acc); color: #fff;
  font-size: .62rem; font-weight: 800; line-height: 16px; text-align: center;
}

/* Свежий комментарий — ярче обводка и метка «новое» */
.fb-item.fresh {
  border-color: var(--acc-line);
  background: var(--acc-soft);
  box-shadow: inset 3px 0 0 var(--acc);
}
.fb-item.fresh .tag {
  font-size: 10px; padding: 1px 6px; border-radius: 6px;
  background: var(--acc-soft); border: 1px solid var(--acc-line);
}

/* Настройки: две ячейки в одной строке (видео + ролик) */
.settings-row { display: flex; gap: 12px; align-items: flex-end; }
.settings-cell { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.settings-cell.grow { flex: 1; }
.settings-cell .seg button { padding: 5px 10px; }
.settings-sub {
  color: var(--ink-dim); font-size: .78rem; margin-top: 8px;
}
.settings-sub b { color: var(--ink); }

@media (max-width: 760px) {
  /* в тесной шапке телефона значок чуть мельче */
  .brand-mark { width: 36px; height: 37px; }
}

/* ============================================================
   v14: актуальность данных, период по группировке, мобильные правки
   ============================================================ */

/* Строка «Данные актуальны на …» — первое, что видно в разделе */
.data-fresh {
  margin: 0 0 10px;
  padding: 0 2px;
  color: var(--ink-dim);
  font-size: .82rem;
  letter-spacing: .01em;
}
.data-fresh b { color: var(--ink); font-weight: 700; }

/* Выбор периода списками (недели / месяцы) */
.date-row.list-row select.pick { min-width: 120px; max-width: 220px; }
.date-row[hidden] { display: none; }

/* ---------- Закреплённый первый столбец в детальных таблицах ----------
   При горизонтальной прокрутке название (клиент, сырьё, ТС) остаётся на
   месте: без него столбцы с цифрами не с чем сопоставить. Фон непрозрачный
   — иначе сквозь него просвечивают уезжающие колонки. */
.tbl-scroll { position: relative; }
.tbl-scroll table th:first-child,
.tbl-scroll table td:first-child {
  position: sticky;
  left: 0;
  z-index: 2;
  background: var(--tbl-sticky);
  box-shadow: 1px 0 0 var(--glass-border);
}
.tbl-scroll table th:first-child { z-index: 3; }

:root { --tbl-sticky: hsl(215 32% 13%); }
html[data-theme="light"] { --tbl-sticky: hsl(210 30% 97%); }

@media (max-width: 900px) {
  /* Детализация справа на телефоне не помещается и дублирует основной
     график — убираем вместе с подсказкой про клик по столбцу. */
  .trend-side { display: none; }
  .trend-main .copy-hint { display: none; }
}

@media (max-width: 760px) {
  /* Длинные числа (7 688 610) не влезали в карточку в альбомной
     ориентации: разрешаем перенос и уменьшаем шрифт по месту. */
  .kpi .kpi-value, .kpi-value {
    font-size: clamp(.95rem, 4.4vw, 1.35rem);
    overflow-wrap: anywhere;
    line-height: 1.15;
  }
  .kpi { min-width: 0; }
  .date-row.list-row select.pick { min-width: 0; flex: 1; }
}

/* ---------- Одиночный выбор из списка (UIC.pickOne) ---------- */
/* Оформление наследуется от mselect: те же панель, тени и отступы —
   выпадающие списки на сайте должны выглядеть одинаково. */
.pick-one .mselect-pop { min-width: 100%; max-height: 320px; }
.pick-one .mselect-list { max-height: 280px; }
.pick-item { cursor: pointer; padding: 6px 10px; border-radius: 8px; }
.pick-item:hover { background: hsla(0, 0%, 100%, .08); }
html[data-theme="light"] .pick-item:hover { background: hsla(215, 40%, 50%, .12); }
.pick-item.on { background: var(--acc-soft); color: var(--ink); font-weight: 700; }

/* Календарики: системный выпадающий календарь остаётся системным,
   но само поле должно быть в тон теме. */
.date-input { color-scheme: dark; }
html[data-theme="light"] .date-input { color-scheme: light; }

/* Закрытый раздел: кнопка приглушена так же, как у разделов в разработке */
.tab.closed { opacity: .45; }
.tab.closed:hover { opacity: .7; }
.closed-stub h2 { margin-bottom: 8px; }
.closed-stub p { color: var(--ink-dim); }

/* ============================================================
   Раздел «ФОТ»: блоки за день / неделю / месяц / год
   ============================================================ */

/* Четыре блока в ряд на широком экране, по два — на среднем, по одному
   на телефоне. Каждый со своим переключателем периода. */
.fot-top {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 12px;
  margin-bottom: 14px;
}
.fot-card { padding: 14px 16px; }
.fot-card .panel-head { margin-bottom: 4px; gap: 10px; align-items: center; }
.fot-card .panel-head h3 { white-space: nowrap; }
.fot-pick { margin-left: auto; min-width: 0; }
.fot-pick .date-input { padding: 4px 8px; font-size: .82rem; }
.fot-pick .mselect-btn { padding: 4px 10px; font-size: .82rem; }

.fot-sub {
  color: var(--ink-faint); font-size: .76rem;
  margin-bottom: 10px; font-variant-numeric: tabular-nums;
}

/* Числа блока — в две колонки: шесть показателей в столбик растянули бы
   карточку на пол-экрана. */
.fot-nums { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 14px; }
.fot-num { display: flex; flex-direction: column; min-width: 0; }
.fot-num-label {
  color: var(--ink-faint); font-size: .68rem;
  letter-spacing: .04em; text-transform: uppercase;
}
.fot-num-value {
  font-size: 1.02rem; font-weight: 800; line-height: 1.2;
  font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}
.fot-num-hint { color: var(--ink-dim); font-size: .7rem; overflow-wrap: anywhere; }

@media (max-width: 760px) {
  .fot-top { grid-template-columns: minmax(0, 1fr); }
  .fot-card .panel-head { flex-wrap: wrap; }
  .fot-pick { margin-left: 0; width: 100%; }
}

/* Выбор года в фильтре периода: появляется, только если данных больше
   чем за один год. */
.year-row { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.year-row .mselect { min-width: 0; }
.year-select .mselect-btn { padding: 4px 10px; font-size: .82rem; }
.year-select .mselect-pop { min-width: 160px; }

/* ---------- Кнопки над таблицами «— детально» ---------- */
.tbl-tools { position: relative; display: flex; gap: 6px; margin-left: auto; }
.icon-btn.small { width: 28px; height: 28px; padding: 0; }
.tbl-menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 60;
  display: none; flex-direction: column; gap: 4px;
  padding: 8px; min-width: 130px;
  background: var(--glass-strong); border: 1px solid var(--glass-border);
  border-radius: var(--radius-s); box-shadow: 0 12px 28px hsla(0,0%,0%,.35);
}
.tbl-tools.open .tbl-menu { display: flex; }
.tbl-menu-title { color: var(--ink-faint); font-size: .72rem; margin-bottom: 2px; }
.tbl-menu button {
  text-align: left; padding: 5px 8px; border-radius: 8px;
  background: none; border: none; color: var(--ink); font: inherit; font-size: .84rem; cursor: pointer;
}
.tbl-menu button:hover { background: var(--acc-soft); }

/* Пояснение к общему периоду: показывается, только когда период пришлось
   подогнать под данные раздела. */
.period-note {
  margin: -4px 0 10px; padding: 6px 10px;
  border-left: 2px solid var(--acc-line);
  background: var(--acc-soft); border-radius: 0 var(--radius-s) var(--radius-s) 0;
  color: var(--ink-dim); font-size: .8rem;
}

/* ---------- Скриншоты в комментариях ---------- */
.fb-attach { display: flex; align-items: center; gap: 10px; margin-top: 8px; flex-wrap: wrap; }
.fb-preview { display: flex; align-items: center; gap: 10px; margin-top: 8px; flex-wrap: wrap; }
.fb-shot { margin-top: 8px; }
.fb-thumb {
  max-width: 180px; max-height: 120px; border-radius: var(--radius-s);
  border: 1px solid var(--glass-border); cursor: zoom-in; display: block;
}
.fb-thumb:hover { border-color: var(--acc-line); }

/* Просмотр картинки поверх страницы */
.lb-scrim {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center;
  background: hsla(0, 0%, 0%, .8);
  opacity: 0; transition: opacity .18s;
  overflow: hidden;
}
.lb-scrim.show { opacity: 1; }
.lb-img {
  max-width: 92vw; max-height: 88vh;
  transform-origin: center center;
  will-change: transform;
  user-select: none; -webkit-user-drag: none;
  box-shadow: 0 20px 60px hsla(0, 0%, 0%, .6);
  border-radius: 6px;
}
.lb-close {
  position: absolute; top: 16px; right: 20px;
  width: 38px; height: 38px; border-radius: 50%;
  background: hsla(0, 0%, 100%, .12); border: 1px solid hsla(0, 0%, 100%, .25);
  color: #fff; font-size: 1.1rem; cursor: pointer;
}
.lb-close:hover { background: hsla(0, 0%, 100%, .22); }
.lb-hint {
  position: absolute; bottom: 18px; left: 50%; transform: translateX(-50%);
  color: hsla(0, 0%, 100%, .65); font-size: .78rem; white-space: nowrap;
}
@media (max-width: 760px) { .lb-hint { display: none; } }

/* ============================================================
   Главная: блоки выручки и выпуска по неделям и месяцам
   ============================================================ */

/* Пара блоков в строке: выручка и выпуск за один и тот же период —
   сравнивать удобно, когда они рядом, а не через весь экран. */
.home-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
  margin-bottom: 14px;
}

.hb { padding: 16px 18px; display: flex; flex-direction: column; }
.hb-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.hb-title { font-weight: 800; font-size: .92rem; }
.hb-period {
  color: var(--ink-faint); font-size: .74rem;
  margin-left: auto; font-variant-numeric: tabular-nums; white-space: nowrap;
}

.hb-total {
  font-size: 2.1rem; font-weight: 800; line-height: 1.1;
  margin: 6px 0 12px; font-variant-numeric: tabular-nums;
}
.hb-unit { font-size: .9rem; font-weight: 700; color: var(--ink-dim); margin-left: 6px; }

.hb-rows { display: flex; flex-direction: column; gap: 4px; }
.hb-row { display: grid; grid-template-columns: 46px 1fr auto; align-items: center; gap: 10px; }
.hb-day {
  color: var(--ink-dim); font-size: .74rem; font-weight: 700; letter-spacing: .04em;
}
.hb-val { font-size: .84rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.hb-row.empty .hb-val, .hb-row.empty .hb-day { color: var(--ink-faint); font-weight: 600; }

/* Полоска под значением: масштаб внутри блока, чтобы провалы ловились
   взглядом, не читая цифры. */
.hb-bar {
  height: 6px; border-radius: 3px;
  background: hsla(0, 0%, 100%, .07); overflow: hidden;
}
.hb-bar i { display: block; height: 100%; border-radius: 3px; background: var(--acc); }
.hb-prod .hb-bar i { background: hsl(var(--hue) 55% 68%); }
html[data-theme="light"] .hb-bar { background: hsla(215, 30%, 50%, .12); }

/* Прошлые периоды — тот же состав, но компактнее: они для сравнения,
   а не для чтения по строкам. */
.hb-small { padding: 12px 14px; }
.hb-small .hb-total { font-size: 1.5rem; margin: 4px 0 8px; }
.hb-small .hb-title { font-size: .84rem; }
.hb-small .hb-row { grid-template-columns: 42px 1fr auto; gap: 8px; }
.hb-small .hb-val { font-size: .78rem; }
.hb-small .hb-bar { height: 5px; }

/* Переход в раздел по клику — только с мышью (см. home.js) */
.hb-link { cursor: pointer; transition: border-color .15s, transform .15s; }
.hb-link:hover { border-color: var(--acc-line); transform: translateY(-1px); }

@media (max-width: 900px) {
  .home-row { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .hb-total { font-size: 1.6rem; }
}

/* Полоса «что показано ниже»: переключение между всем периодом и одним
   выбранным на диаграмме столбцом. */
.drill-bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: -4px 0 14px; padding: 8px 14px;
  border: 1px solid var(--glass-border); border-radius: var(--radius-s);
  background: hsla(0, 0%, 100%, .04);
}
html[data-theme="light"] .drill-bar { background: hsla(0, 0%, 100%, .5); }
.drill-text { color: var(--ink-dim); font-size: .82rem; margin-right: auto; }
.drill-bar .btn.active { background: var(--acc-soft); border-color: var(--acc-line); color: var(--ink); }

/* Таблицы «— детально» занимают всю высоту панели: иначе панель с
   короткой таблицей выглядит наполовину пустой рядом с соседней. */
.grid-2 > .panel { display: flex; flex-direction: column; }
.grid-2 > .panel > .tbl-scroll { flex: 1; min-height: 0; }

/* ============================================================
   Новости: панель у правого края + карточки в админке
   ============================================================ */

/* Панель выезжает так же, как настройки, и по той же дорожке: два разных
   способа показать боковую панель на одной странице выглядели бы как
   недоделка. Шире настроек — здесь читают текст, а не двигают ползунки. */
.newsfeed {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 90;
  width: min(420px, 94vw);
  border-radius: 0; border-width: 0 0 0 1px;
  background: var(--glass-strong);
  padding: 18px 20px 20px;
  transform: translateX(105%);
  transition: transform .28s cubic-bezier(.2,.8,.2,1);
  display: flex; flex-direction: column;
}
.newsfeed.open { transform: none; }
.newsfeed-head {
  display: flex; justify-content: space-between; align-items: center;
  gap: 10px; margin-bottom: 12px; flex: none;
}
.newsfeed-head h2 { margin: 0; font-size: 1.1rem; }

/* Прокручивается только лента: заголовок с крестиком остаётся на месте,
   иначе на длинной ленте закрыть панель можно было бы, лишь пролистав
   её обратно наверх. */
.newsfeed-body { flex: 1; min-height: 0; overflow-y: auto; padding-right: 2px; }
.news-empty { color: var(--ink-faint); font-size: .88rem; padding: 24px 2px; text-align: center; }

.news-item {
  border: 1px solid var(--glass-border); border-radius: var(--radius-s);
  padding: 12px 14px; margin-bottom: 10px; background: hsla(0,0%,100%,.03);
}
html[data-theme="light"] .news-item { background: hsla(0,0%,100%,.45); }
.news-meta {
  display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap;
  font-size: .76rem; color: var(--ink-faint); margin-bottom: 4px;
}
.news-date { font-variant-numeric: tabular-nums; }
.news-title { margin: 0 0 6px; font-size: .98rem; font-weight: 800; overflow-wrap: anywhere; }
.news-text { font-size: .9rem; line-height: 1.5; overflow-wrap: anywhere; }

/* Непрочитанное — той же меткой, что свежий комментарий: человек уже
   знает, что означает эта полоска слева. */
.news-item.fresh {
  border-color: var(--acc-line);
  background: var(--acc-soft);
  box-shadow: inset 3px 0 0 var(--acc);
}
.news-item.fresh .tag {
  font-size: 10px; padding: 1px 6px; border-radius: 6px;
  background: var(--acc-soft); border: 1px solid var(--acc-line);
}

/* Админка: заголовок и текст — одним столбцом, с одинаковым зазором */
.news-form { display: flex; flex-direction: column; gap: 8px; }

/* Админка: строка «кто прочитал» под новостью */
.news-readers { margin-top: 8px; font-size: .76rem; color: var(--ink-faint); }
.news-readers b { color: var(--ink-dim); }
.news-pending { overflow-wrap: anywhere; }

@media (max-width: 760px) {
  .newsfeed { width: 100%; padding: 14px; }
}

/* ============================================================
   Розница X5: карта регионов, шапка раздела, уровень сервиса
   ============================================================ */

:root { --map-empty: hsla(var(--hue), 25%, 92%, .07); }
html[data-theme="light"] { --map-empty: hsla(var(--hue), 30%, 40%, .09); }

/* Шапка раздела: период данных, счётчики, кнопка возврата карты */
.retail-head {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 0 0 10px; padding: 0 2px;
  color: var(--ink-dim); font-size: .82rem;
}
.retail-head .retail-span { color: var(--ink); font-weight: 700; }
.tag.warn { border-color: hsla(38, 90%, 60%, .5); background: hsla(38, 90%, 60%, .16); }

/* Пока идёт запрос к серверу — гасим содержимое, но не блокируем фильтры:
   человек может продолжать выбирать, запросы склеиваются по времени. */
.frame.busy .grid-kpi, .frame.busy .chart-wrap, .frame.busy .tbl-scroll { opacity: .55; }
.frame.busy { transition: opacity .15s; }

/* ---------- Карта ---------- */

/* Показатели слева, карта справа. Ширина колонки подобрана так, чтобы
   в неё вставали два столбца карточек: семь показателей в один столбец
   вытянулись бы вдвое выше карты. */
.retail-top {
  display: grid; grid-template-columns: minmax(300px, 380px) minmax(0, 1fr);
  gap: 14px; align-items: start; margin-bottom: 14px;
}
.retail-top > * { min-width: 0; }
.retail-top .retail-kpi { grid-template-columns: repeat(2, minmax(0, 1fr)); margin-bottom: 0; }
.retail-top .map-panel { margin-bottom: 0; }
.retail-top.map-off { grid-template-columns: minmax(0, 1fr); }
.retail-top.map-off .retail-kpi { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }

.map-panel .head-tools { gap: 12px; }
.map-body { position: relative; height: 430px; margin: 6px 0 4px; }
.ru-map { width: 100%; height: 100%; display: block; cursor: grab; touch-action: none; }
.ru-map.dragging { cursor: grabbing; }

.map-region {
  stroke: var(--glass-border);
  stroke-width: var(--map-stroke, 1px);
  vector-effect: non-scaling-stroke;
  cursor: pointer;
  transition: opacity .15s;
}
.map-region:hover { stroke: var(--acc); stroke-width: 2px; }
.map-region.dim { opacity: .7; }

/* Выбранный регион обводим, а не перекрашиваем: заливка занята
   показателем, и подменять её выделением значит терять данные.
   Обводка лежит отдельным слоем поверх точек магазинов. */
.map-sel { pointer-events: none; }
.map-outline {
  fill: none; stroke: var(--acc); stroke-width: 2.6px;
  vector-effect: non-scaling-stroke;
  filter: drop-shadow(0 0 4px var(--acc));
}

/* Города: прозрачность делает скопление читаемым как плотность, а не
   сплошным пятном — в европейской части их сотни. */
.map-dot {
  fill: hsla(28, 92%, 62%, .62);
  stroke: hsla(0, 0%, 100%, .5); stroke-width: .4px;
  vector-effect: non-scaling-stroke; cursor: pointer;
}
html[data-theme="light"] .map-dot { fill: hsla(18, 88%, 48%, .78); }

.map-foot { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.map-legend { display: flex; align-items: center; gap: 8px; font-size: .76rem; color: var(--ink-dim); }
.map-legend .legend-label { font-weight: 700; color: var(--ink); }
/* Рамки нет намеренно: с ней на тёмном конце оставалась светлая полоска
   в пиксель — граница просвечивала сквозь заливку. Контур даёт тень
   внутрь, она ложится поверх градиента и разрывов не оставляет. */
.legend-bar {
  width: 130px; height: 10px; border-radius: 5px; border: 0;
  box-shadow: inset 0 0 0 1px var(--glass-border);
  background-image: linear-gradient(90deg,
    hsl(var(--hue) calc(var(--sat) * .35%) 26%),
    hsl(var(--hue) calc(var(--sat) * 1%) 70%));
  background-origin: border-box;
}
html[data-theme="light"] .legend-bar {
  background-image: linear-gradient(90deg,
    hsl(var(--hue) calc(var(--sat) * .35%) 92%),
    hsl(var(--hue) calc(var(--sat) * 1%) 46%));
}
/* У «дней запаса» и списаний хорошо — это мало, и шкала перевёрнута */
.legend-bar.inv { transform: scaleX(-1); }
.legend-min, .legend-max { font-variant-numeric: tabular-nums; }

.map-tip {
  position: fixed; z-index: 120; pointer-events: none;
  padding: 8px 11px; border-radius: var(--radius-s);
  background: var(--glass-strong); border: 1px solid var(--glass-border);
  backdrop-filter: blur(var(--glass-blur));
  color: var(--ink); font-size: .8rem; line-height: 1.45;
  box-shadow: var(--shadow);
  opacity: 0; transition: opacity .12s;
  max-width: 260px;
}
.map-tip.show { opacity: 1; }
.map-fail { padding: 40px 20px; text-align: center; color: var(--ink-dim); }

/* ---------- Уровень сервиса ---------- */

.sl-row { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); gap: 14px; }
.sl-row .chart-wrap { height: 300px; }
.sl-row .tbl-scroll { max-height: 300px; }
#rSlNote { display: block; margin: -2px 0 10px; }

@media (max-width: 1200px) {
  /* Узкий экран: карта под показателями, а не рядом — иначе от неё
     остаётся полоска, на которой ничего не разобрать. */
  .retail-top { grid-template-columns: minmax(0, 1fr); }
  .retail-top .retail-kpi { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
}
@media (max-width: 1000px) {
  .sl-row { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 760px) {
  .map-body { height: 300px; }
  .map-panel .head-tools { gap: 8px; }
  .legend-bar { width: 80px; }
}

/* Срез: таблице нужно больше места — в ней восемь колонок, диаграмме
   хватает и меньшего. */
.retail-break { grid-template-columns: minmax(0, .82fr) minmax(0, 1.18fr); }
@media (max-width: 1000px) { .retail-break { grid-template-columns: minmax(0, 1fr); } }

/* Сортировка таблиц «— детально»: заголовок кликабелен, направление
   показывает треугольник.
   Заголовок не переносится по словам: стрелка занимает место всегда, и
   при узкой колонке она срывалась на вторую строку — шапка прыгала по
   высоте при каждом клике. Вместо переноса таблица получает
   горизонтальную прокрутку: лучше сдвинуть таблицу, чем ломать шапку. */
.tbl thead th {
  cursor: pointer; user-select: none; position: relative;
  white-space: nowrap;
}
.tbl thead th:hover { color: var(--ink); }
.tbl thead th::after {
  content: "▲"; font-size: 8px; opacity: 0; margin-left: 5px;
  display: inline-block; vertical-align: middle;
}
.tbl thead th.sort-asc::after { opacity: .8; }
.tbl thead th.sort-desc::after { content: "▼"; opacity: .8; }
.tbl-scroll { overflow-x: auto; }

/* Свёрнутая карта: прячется только полотно, шапка панели с кнопкой
   остаётся на месте — иначе кнопка возврата оказывалась в другом конце
   экрана, и её приходилось искать. */
.map-panel.collapsed .map-body,
.map-panel.collapsed .map-foot,
.map-panel.collapsed .map-mismatch,
.map-panel.collapsed #mapMetricSeg,
.map-panel.collapsed .chk { display: none; }
.map-panel.collapsed { padding-bottom: 10px; }
/* Ширина кнопки фиксирована: «Скрыть карту» и «Показать карту» разной
   длины, и без этого кнопка на пару пикселей прыгала при каждом нажатии. */
#mapHide { min-width: 128px; }

/* Подписи регионов внутри контуров. Обводка того же цвета, что фон
   панели, — иначе на светлой заливке чёрный текст сливается с границей
   соседней области. */
.map-labels { pointer-events: none; }
.map-label {
  fill: var(--ink); font-weight: 700; text-anchor: middle;
  dominant-baseline: middle;
  stroke: var(--glass-strong); paint-order: stroke fill;
  stroke-linejoin: round;
}
html[data-theme="light"] .map-label { stroke: hsla(0, 0%, 100%, .85); }

.map-mismatch {
  margin: 4px 0 8px; padding: 7px 11px; font-size: .78rem;
  border: 1px solid hsla(38, 90%, 60%, .45);
  background: hsla(38, 90%, 60%, .12);
  border-radius: var(--radius-s); color: var(--ink-dim);
}

/* ---------- Закреплённая панель фильтров ---------- */

.filters { position: relative; }

/* Замочек в правом верхнем углу панели. Внутри панели, а не рядом с ней:
   так он не занимает отдельной строки и не сдвигает раскладку. */
.pin-btn {
  position: absolute; top: 6px; right: 8px;
  width: 26px; height: 26px; padding: 0;
  display: grid; place-items: center;
  border: 1px solid transparent; border-radius: 8px;
  background: transparent; color: var(--ink-faint);
  cursor: pointer; transition: color .15s, background .15s, border-color .15s;
}
.pin-btn:hover { color: var(--ink); background: var(--glass-border); }
.pin-btn.on { color: var(--acc); border-color: var(--acc-line); background: var(--acc-soft); }

/* Закреплённая панель едет вместе со страницей. top — под шапкой:
   она у нас прилипшая, и без отступа фильтры уезжали бы под неё. */
.filters.pinned {
  position: sticky; top: calc(var(--topbar-h, 56px) + 10px); z-index: 45;
  box-shadow: var(--shadow);
}
@media (max-width: 760px) {
  /* На телефоне закреплённая панель съедала бы пол-экрана. */
  .filters.pinned { position: static; box-shadow: none; }
  .pin-btn { display: none; }
}

/* ---------- Одинаковый размер полей периода при любой грануляции ---------- */

/* Раньше поля были разной ширины: календарик даты, короткий список
   недель и длинный список месяцев. При смене грануляции колонка меняла
   ширину, и вся панель фильтров подпрыгивала. Теперь ширина и шрифт
   заданы жёстко — по календарику, как в режиме дней. */
.period-col { width: 250px; }
/* Высота тоже фиксирована. В режиме дней стоят два календарика, в
   режимах недель и месяцев — два списка; ряды разной высоты, и панель
   подпрыгивала по вертикали при каждом переключении. Высота — по
   календарикам, как в режиме дней. */
/* Оба ряда — календарики и списки — занимают одинаковую высоту: в
   режиме дней это один ряд полей, в неделях и месяцах два. Без этого
   колонка периода становилась на четыре пикселя выше, и панель
   фильтров подпрыгивала при переключении. */
.period-col .period-controls { min-height: 64px; }
.period-col .date-row {
  flex-wrap: nowrap; min-height: 64px; align-items: center;
}
/* Списки один под другим: две строки по 30 px плюс зазор. Высота
   колонки от этого не меняется — она задана .period-controls. */
.period-col .date-row.list-row {
  flex-direction: column; align-items: stretch; gap: 4px; min-height: 30px;
}
.period-col .list-row .mselect { flex: 0 0 30px; }
.period-col .date-input,
.period-col select.date-input.wk {
  flex: 1 1 0; width: auto; min-width: 0;
  font-size: .82rem; height: 30px; line-height: 20px;
  padding: 4px 8px; box-sizing: border-box;
}
/* Списки недель и месяцев — те же размеры, что у календариков: это
   один и тот же выбор периода, просто в другой единице. */
.period-col .list-row .mselect { flex: 1 1 0; min-width: 0; }
/* Кнопка списка занимает всю ширину поля: без этого она сжималась по
   тексту, а стрелка ▾ рисуется по правому краю обёртки и оставалась
   висеть далеко в стороне. */
.period-col .list-row .mselect-btn {
  width: 100%; height: 30px; line-height: 20px;
  font-size: .82rem; padding: 4px 22px 4px 8px; box-sizing: border-box;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Стрелку у списков рисует сам браузер и место под неё не резервирует —
   добавляем справа, иначе длинное «Сентябрь 2026» лезет под неё. */
.period-col select.date-input.wk { padding-right: 4px; text-overflow: ellipsis; }
.period-col .date-row span,
.period-col .wk-sep { flex: 0 0 auto; }
/* Переключателю грануляции нужно место: рядом с колонкой периода в
   250 px ему оставалось несколько пикселей, и кнопки налезали на
   соседний блок. Столбиком они стоят намеренно (см. .filters.compact) —
   так блок группировки не выше блока периода. */
.filter-block.narrow.mode-col { min-width: 96px; }
.filters .seg { flex-wrap: nowrap; }
/* Место под замочек в правом верхнем углу, чтобы он не ложился поверх
   подписи крайнего фильтра. */
.filters { padding-right: 42px; }

@media (max-width: 760px) {
  .period-col { width: 100%; }
  .filter-block.narrow.mode-col { min-width: 0; }
  .filters { padding-right: 14px; }
}

/* Приглушённые пункты мультиселекта: есть в списке, но не связаны с тем,
   что выбрано в соседнем фильтре. Не убираем их совсем — выбрать такую
   позицию законно, просто она вряд ли нужна. */
.mselect-item.faded { opacity: .45; }
.mselect-item.faded:hover { opacity: .75; }
.mselect-sep {
  padding: 6px 10px 2px; font-size: .68rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-faint);
  border-top: 1px solid var(--glass-border); margin-top: 4px;
}

/* ---------- Пелена на время пересчёта ---------- */

.frame-veil {
  position: absolute; inset: 0; z-index: 30;
  display: grid; place-items: center;
  background: var(--bg-veil, hsla(215, 40%, 6%, .55));
  backdrop-filter: blur(1.5px);
  opacity: 0; pointer-events: none;
  transition: opacity .18s;
  border-radius: var(--radius-l, 16px);
}
html[data-theme="light"] .frame-veil { --bg-veil: hsla(0, 0%, 100%, .6); }
/* Пока пелена не показана, она не должна перехватывать клики: расчёт
   может закончиться раньше, чем она появится. */
.frame-veil.show { opacity: 1; pointer-events: auto; }
.frame { position: relative; }
