/* CRM «Сытый Япончик».
   Визуальный язык снят с референса Mesh CRM: тёмно-синие панели, кислотный
   салатовый акцент, тёплый светлый фон, крупные числа, мягкие скругления.
   Навигация сверху пилюлей, а не сайдбаром — так рабочее поле шире, а разделы
   читаются как режимы работы, а не как дерево.

   Отступление от референса одно и намеренное: там много текста в 11–13px, а
   здесь нижняя граница 14px для подписей и 16px для всего остального. Числа,
   по которым принимают решения, не должны требовать прищура. По APCA пары
   выдерживают с запасом: тёмный на белом Lc 104, белый на синем Lc 104,
   салатовый на синем Lc 88. Приглушённый текст на тёмных панелях — 80 % белого
   (Lc 77), а не 60 % (Lc 52, годится только для крупного).
*/

@font-face {
  font-family: Onest;
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/onest-400-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: Onest;
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/onest-400-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: Onest;
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/onest-500-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: Onest;
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/onest-500-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: Onest;
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/onest-600-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: Onest;
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/onest-600-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: Onest;
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/onest-700-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: Onest;
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/onest-700-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* ---------- токены ---------- */

:root {
  --navy: #16264d;          /* тёмные панели и навигация */
  --navy-soft: #1d3160;     /* блок внутри тёмной панели */
  --ink: #0f1a33;           /* основной текст, Lc 104 на белом */
  --muted: #4e5c75;         /* вторичный текст, Lc 84 на белом */
  --lime: #d8f34a;          /* акцент: активное, выгодное, выделенное */
  --lime-deep: #b9d32e;     /* бордюр и наведение на салатовом */

  --bg: #faf9f5;
  --card: #ffffff;
  --surface: #f4f7fb;       /* подложка внутри карточки */
  --line: #e2e8f1;
  --on-navy: #ffffff;
  --on-navy-dim: #d0d4db;   /* 80 % белого: Lc 77, читается */

  --good: #3f7d2e;
  --warn: #a8521a;

  --r-s: 7px;
  --r-m: 20px;
  --r-l: 30px;
  --r-pill: 999px;

  --shadow: 0 24px 48px -32px rgba(22, 38, 77, 0.3);
  --page: 1360px;
  --font: Onest, -apple-system, "Segoe UI", system-ui, sans-serif;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 16px;
  line-height: 24px;
  -webkit-font-smoothing: antialiased;
}

/* Контур фокуса — два слоя. Трёхпиксельная сплошная рамка с отступом читалась
   на скруглённом поле заплаткой поверх вёрстки: толстая, с острыми краями и
   сама по себе. Тонкая линия держит тот же контраст, мягкое кольцо вокруг
   гасит её край — видно так же хорошо, а смотрится частью поля. */
:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
  box-shadow: 0 0 0 5px rgba(22, 38, 77, 0.13);
}
.topbar :focus-visible, .panel--navy :focus-visible {
  outline-color: var(--lime);
  box-shadow: 0 0 0 5px rgba(216, 243, 74, 0.2);
}
/* У поля своё. Обводка с отступом давала на нём двойной контур: сначала
   рамка поля, потом зазор, потом линия — три кольца вокруг одного окошка.
   Поэтому здесь обводка ложится прямо на рамку: одно чёткое кольцо по краю
   поля и мягкий ореол за ним. Поле «включилось», а не обведено снаружи. */
.fld:focus-visible, .fld:focus {
  outline: 2px solid var(--navy);
  outline-offset: -1px;
  border-color: var(--navy);
  box-shadow: 0 0 0 4px rgba(22, 38, 77, 0.12);
}

/* Переходы там, где состояние меняется от руки: наведение, фокус, нажатие.
   Только цвет, рамка и тень — ни одно из них не пересчитывает раскладку,
   поэтому список из семидесяти строк от этого не тяжелеет. Нажатие отвечает
   сдвигом на пиксель: на сенсорном экране это единственный отклик, который
   видно до того, как придёт ответ сервера. */
.btn, .fld, .icon-btn, .lnk, .hint, .sw, .seg button, .tabs a, .grp__add,
.grp__fold, .chip, .tag, tbody tr[aria-selected] td {
  transition: background-color 0.14s ease, border-color 0.14s ease,
    color 0.14s ease, box-shadow 0.14s ease, outline-color 0.14s ease;
}
.btn:active, .icon-btn:active, .seg button:active { transform: translateY(1px); }
@media (prefers-reduced-motion: reduce) {
  .btn:active, .icon-btn:active, .seg button:active { transform: none; }
  .btn, .fld, .icon-btn, .lnk, .hint, .sw, .seg button, .tabs a, .grp__add,
  .grp__fold, .chip, .tag, tbody tr[aria-selected] td { transition: none; }
}

.wrap {
  max-width: var(--page);
  margin: 0 auto;
  padding: 18px clamp(16px, 2.2vw, 28px) 56px;
}

/* ---------- верхняя навигация ---------- */

.topbar {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 22px;
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  min-height: 44px;
  font-size: 19px;
  font-weight: 600;
  white-space: nowrap;
}
/* Знак Mesh: четыре формы, у учёта подсвечен квадрат. Подложки под знаком
   нет — он сам себе форма, а в коробке читался бы как кнопка. */
.brand__mark { width: 28px; height: 28px; flex: none; display: block; }
.brand__mark svg { width: 100%; height: 100%; display: block; }
.brand__name span { color: var(--muted); font-weight: 400; font-size: 16px; }

/* Чьё хозяйство. Учёт один на ресторан, но продукт называется Mesh crm, и без
   этой приписки непонятно, в чью базу ты смотришь. На узком экране уходит:
   там место дороже отдать разделам. */
.brand__who {
  padding-left: 11px;
  border-left: 1px solid var(--line);
  color: var(--muted);
  font-weight: 400;
  font-size: 15px;
}
@media (max-width: 1240px) { .brand__who { display: none; } }

/* Выбор точки. Рядом с именем хозяйства, потому что отвечает на тот же
   вопрос — в чьи цифры ты смотришь, — и потому что ответ должен быть виден
   из любого раздела, а не только из того, где его меняют.
   На узком экране название хозяйства уходит, а точка остаётся: она важнее. */
.venue { display: inline-flex; align-items: center; }
.venue__sel {
  min-height: 34px;
  max-width: 190px;
  padding: 4px 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-size: 15px;
  font-weight: 500;
  cursor: pointer;
}
.venue__sel:focus-visible { outline: 2px solid var(--navy); outline-offset: 2px; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; border: 0; overflow: hidden; white-space: nowrap;
  clip: rect(0 0 0 0); clip-path: inset(50%);
}

.tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  padding: 5px;
  border-radius: var(--r-pill);
  background: var(--navy);
}
.tabs a {
  display: inline-flex;
  align-items: center;
  min-height: 38px;
  padding: 6px 16px;
  border-radius: var(--r-pill);
  color: var(--on-navy-dim);
  text-decoration: none;
  font-size: 15px;
  white-space: nowrap;
}
.tabs a:hover { color: var(--on-navy); background: rgba(255, 255, 255, 0.08); }
.tabs a[aria-current="page"] { background: var(--lime); color: var(--ink); font-weight: 600; }

.topbar__end { margin-left: auto; display: flex; align-items: center; gap: 10px; }

/* ---------- шапка раздела ---------- */

.head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 18px;
  margin-bottom: 18px;
}
.head__title h1 {
  margin: 0;
  font-size: clamp(30px, 3.4vw, 44px);
  line-height: 1.04;
  font-weight: 600;
  letter-spacing: -0.015em;
}
.head__sub { margin: 4px 0 0; color: var(--muted); font-size: 15px; }
.head__end { margin-left: auto; display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }

.seg {
  display: inline-flex;
  gap: 2px;
  padding: 4px;
  border-radius: var(--r-pill);
  background: var(--card);
  border: 1px solid var(--line);
}
.seg button {
  min-height: 38px;
  padding: 5px 16px;
  border: none;
  border-radius: var(--r-pill);
  background: none;
  color: var(--muted);
  font: inherit;
  font-size: 15px;
  cursor: pointer;
}
.seg button[aria-pressed="true"] { background: var(--navy); color: var(--on-navy); font-weight: 600; }

.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 9px 10px 9px 22px;
  border: none;
  border-radius: var(--r-pill);
  background: var(--navy);
  color: var(--on-navy);
  font: inherit;
  font-size: 16px;
  font-weight: 500;
  cursor: pointer;
  text-decoration: none;
}
.btn i {
  width: 28px; height: 28px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--lime);
  color: var(--ink);
  font-style: normal;
  font-size: 15px;
}
.btn--lime { background: var(--lime); color: var(--ink); font-weight: 600; }
.btn--lime i { background: var(--navy); color: var(--lime); }

/* ---------- сетка и карточки ---------- */

.row { display: grid; gap: 14px; }
.row--3 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.row--2 { grid-template-columns: repeat(auto-fit, minmax(380px, 1fr)); }
.row--split { grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr); }
/* Список накладных: шесть колонок, и переносится из них только название
   поставщика. Пока ему доставалось 175 пикселей, «Альмин Провижн Сервис -
   Канцелярий» ложился в три строки, и высота строк в таблице скакала.
   Правило объявлено до медиазапроса на 1100 — иначе перебило бы его. */
.row--split--list { grid-template-columns: minmax(0, 1.68fr) minmax(0, 1fr); }
.row + .row { margin-top: 14px; }

.card {
  background: var(--card);
  border-radius: var(--r-m);
  padding: 20px 22px;
  min-width: 0;
}
.card--flat { border: 1px solid var(--line); }
.card--pad0 { padding: 0; overflow: hidden; }
.panel--navy {
  background: var(--navy);
  color: var(--on-navy);
  border-radius: var(--r-l);
  padding: 22px 24px;
  box-shadow: var(--shadow);
  min-width: 0;
}
.panel--navy .muted { color: var(--on-navy-dim); }

.card__head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}
.card__head h2 { margin: 0; font-size: 17px; font-weight: 600; }
.card__head .muted { margin-left: auto; font-size: 15px; }
.muted { color: var(--muted); }

/* ---------- метрика ---------- */

.metric__label { margin: 0; font-size: 15px; color: var(--muted); }
.metric__value {
  margin: 10px 0 0;
  font-size: clamp(32px, 3.6vw, 46px);
  line-height: 1.02;
  font-weight: 500;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.metric__value small { font-size: 0.5em; font-weight: 400; color: var(--muted); }
.delta {
  display: inline-block;
  margin-top: 12px;
  padding: 4px 12px;
  border-radius: var(--r-pill);
  background: var(--lime);
  font-size: 14px;
  font-weight: 500;
}
.delta--down { background: #f7ddd0; }
.delta--flat { background: var(--surface); color: var(--muted); }

/* ---------- дашборд ---------- */

/* Раскладка референса: числа и план в одной карточке, каналы плитками рядом,
   часы и топ — в одной тёмной панели. Шесть отдельных карточек заставляли глаз
   собирать картину заново на каждой. */
.dash { display: flex; flex-direction: column; gap: 16px; }
.dash__top { display: flex; flex-wrap: wrap; gap: 16px; align-items: stretch; }
.dash__main { flex: 2 1 540px; min-width: 0; display: flex; flex-direction: column; gap: 26px; }
.dash__side { flex: 1 1 320px; min-width: 0; display: flex; flex-direction: column; gap: 18px; }

/* Полупрозрачная карточка на песочном фоне — как в референсе. */
.card--glass {
  background: rgba(255, 255, 255, 0.62);
  border: 1px solid #fff;
  border-radius: var(--r-l);
  padding: 26px;
  box-shadow: var(--shadow);
}

.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 20px; }
.kpi__label { margin: 0; font-size: 15px; color: var(--muted); }
.kpi__val { display: flex; align-items: baseline; gap: 6px; margin: 10px 0 0; }
.kpi__pre { font-size: 16px; color: var(--muted); }
.kpi__num { font-size: 36px; font-weight: 500; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }

.plan { display: flex; flex-direction: column; gap: 12px; }
.plan__title { margin: 0; font-size: 15px; color: var(--muted); }
.plan__row {
  display: grid;
  grid-template-columns: minmax(120px, auto) minmax(0, 3fr) 54px;
  align-items: center;
  gap: 14px;
  font-size: 15px;
}
.plan__row > span:first-child { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.plan__bar { height: 10px; border-radius: var(--r-pill); background: #dfe5ef; overflow: hidden; }
/* Полоска в полоску — так она читается как план, а не как заливка факта. */
.plan__bar i {
  display: block;
  height: 100%;
  border-radius: var(--r-pill);
  background: repeating-linear-gradient(-45deg, var(--lime-deep) 0 4px, var(--lime) 4px 8px);
}
.plan__pct { text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; }
.plan__tail { grid-column: 2 / -1; font-size: 15px; color: var(--muted); }
.plan__note { margin: 4px 0 0; font-size: 15px; color: var(--muted); }

/* ---------- точки сети ---------- */

/* Сначала одна полоса про сеть целиком, под ней карточки точек. Полоса
   тёмная, карточки белые: граница между «сетью» и «каждой по отдельности»
   видна без заголовков, а они на этом экране лишние — он весь про это. */
.netbar {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
  gap: 10px;
  padding: 10px;
  margin-bottom: 14px;
  background: var(--navy);
  border-radius: var(--r-m);
  color: var(--on-navy);
}
.netbar__cell { padding: 14px 16px; border-radius: 14px; background: var(--navy-soft); }
.netbar__cell span { display: block; font-size: 15px; color: var(--on-navy-dim); }
.netbar__cell b {
  display: block;
  margin-top: 6px;
  font-size: 25px;
  font-weight: 600;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.netbar__cell i {
  display: block;
  margin-top: 4px;
  font-size: 14px;
  font-style: normal;
  color: var(--on-navy-dim);
}
/* План дня салатовый: на него смотрят первым, и он отвечает «добираем ли». */
.netbar__cell--lime { background: var(--lime); color: var(--ink); }
.netbar__cell--lime span, .netbar__cell--lime i { color: #4a5a12; }

/* На телефоне пять клеток в столбик — это экран прокрутки до карточек.
   Два столбца, план во всю ширину: он главный и читается первым. */
@media (max-width: 560px) {
  .netbar { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .netbar__cell { padding: 12px 13px; }
  .netbar__cell b { font-size: 21px; }
  .netbar__cell--lime { grid-column: 1 / -1; }
}

.venues { display: grid; grid-template-columns: repeat(auto-fit, minmax(330px, 1fr)); gap: 14px; }
/* Одна точка не должна растягиваться на весь экран: карточка на 1 300
   пикселей читается как таблица, у которой отвалились столбцы. */
.venues > .vcard:only-child { max-width: 560px; }

.vcard {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 18px 20px 14px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-m);
  cursor: pointer;
}
.vcard:hover { border-color: var(--navy); }
.vcard__top { display: flex; align-items: flex-start; gap: 12px; }
.vcard__who { flex: 1; min-width: 0; }
.vcard__who h3 { margin: 0; font-size: 19px; font-weight: 600; }
.vcard__who p {
  margin: 3px 0 0;
  font-size: 15px;
  color: var(--muted);
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.vcard__state { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 5px; }

.vpill {
  padding: 3px 11px;
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--muted);
  font-size: 14px;
  white-space: nowrap;
}
.vpill--work { background: #e7f2d8; color: #2f5119; font-weight: 600; }
/* Точка перед словом: «работает» читается взглядом ещё до текста. */
.vpill--work::before {
  content: '';
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 6px;
  border-radius: 50%;
  background: #5f9a3f;
  vertical-align: 1px;
}
.vpill--later { background: #fae8cd; color: #5f2d07; }
.vpill--work-now { background: var(--navy); color: var(--on-navy); }

.vcard__sum { display: flex; align-items: baseline; gap: 6px; margin: 0; }
.vcard__sum span { font-size: 16px; color: var(--muted); }
/* За какой срок число: без подписи «55 тыс» на карточке читается как сегодня. */
.vcard__sum i { margin-left: auto; font-size: 14px; font-style: normal; color: var(--muted); }
.vcard__sum b {
  font-size: 34px;
  font-weight: 500;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}

.vcard__stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.vcard__stats > div { min-width: 0; padding: 10px 12px; border-radius: 12px; background: var(--surface); }
.vcard__stats span {
  display: block;
  font-size: 14px;
  color: var(--muted);
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.vcard__stats b {
  display: block;
  margin-top: 2px;
  font-size: 17px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.vcard__plan { display: flex; flex-direction: column; gap: 7px; }
.vcard__planhead {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 15px;
  color: var(--muted);
}
.vcard__planhead b { color: var(--ink); font-variant-numeric: tabular-nums; }
.vcard__plan p { margin: 0; font-size: 14px; color: var(--muted); }

.vcard__foot {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: auto;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}
.ava {
  flex: none;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--navy);
  color: var(--on-navy);
  font-size: 14px;
  font-weight: 600;
}
.ava--none { background: var(--surface); border: 1px dashed var(--line); }
.vcard__crew { flex: 1; min-width: 0; }
.vcard__crew b {
  display: block;
  font-size: 16px;
  font-weight: 500;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.vcard__crew span { display: block; font-size: 14px; color: var(--muted); }
.vcard__go { flex: none; background: var(--surface); }

/* Дней в периоде до девяноста: подписи мельче часовых, иначе они слипаются. */
.vdays span { font-size: 13px; }

/* Что заканчивается на складе — в тёмной панели рядом с графиком. */
.low { display: flex; flex-direction: column; gap: 8px; }
.low__row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-radius: 14px;
  background: var(--navy-soft);
}
.low__name { flex: 1; min-width: 0; }
.low__name b {
  display: block;
  font-size: 16px;
  font-weight: 500;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.low__name > span { display: block; font-size: 14px; color: var(--on-navy-dim); }
.low__row .pay { flex: none; }

.chan { display: flex; gap: 8px; align-items: flex-end; flex: 1; min-height: 168px; }
.chan__tile {
  flex: 1 1 0;
  min-width: 0;
  border-radius: var(--r-m);
  padding: 14px;
  background: var(--surface);
  border: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 8px;
}
.chan__tile--lead { background: var(--lime); border-color: var(--lime-deep); }
.chan__pct { font-size: 19px; font-weight: 600; font-variant-numeric: tabular-nums; }
.chan__name { font-size: 15px; color: var(--muted); overflow-wrap: anywhere; }
.chan__tile--lead .chan__name { color: #4a5a12; }
.chan__foot { display: flex; justify-content: space-between; align-items: center; gap: 10px;
  font-size: 15px; color: var(--muted); }
.chan__foot b { color: var(--ink); font-variant-numeric: tabular-nums; }

/* Тёмная панель: часы и топ стоят рядом, а не в двух панелях через зазор. */
.board {
  background: var(--navy);
  border-radius: 32px;
  padding: 26px;
  color: var(--on-navy);
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
}
.board__left { flex: 2 1 480px; min-width: 0; display: flex; flex-direction: column; gap: 18px; }
.board__right { flex: 1 1 300px; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.board__head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.board__head h2 { margin: 0; font-size: 19px; font-weight: 500; }
.board__head span { font-size: 15px; color: var(--on-navy-dim); }
/* Заголовок и подпись под ним — одной колонкой: справа от них встаёт
   переключатель, и подпись «пик 13:00» не должна его отодвигать. */
.board__title { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.board .hours { height: 200px; }

/* Переключатель на тёмной панели: светлый вариант на синем читался бы
   заплаткой — тот же элемент, но в цветах панели. */
.seg--onnavy { background: var(--navy-soft); border-color: rgba(255, 255, 255, 0.16); padding: 3px; }
.seg--onnavy button { min-height: 32px; padding: 4px 14px; font-size: 15px; color: var(--on-navy-dim); }
.seg--onnavy button:hover { color: var(--on-navy); }
.seg--onnavy button[aria-pressed="true"] { background: var(--lime); color: var(--ink); }

/* Весь список позиций — строкой под топом: не кнопка-действие, а продолжение
   списка, поэтому и выглядит как его шестая строка. */
.rank__all {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  margin-top: 2px;
  padding: 11px 16px;
  border: 1px dashed rgba(255, 255, 255, 0.28);
  border-radius: 14px;
  background: none;
  color: var(--on-navy-dim);
  font: inherit;
  font-size: 16px;
  cursor: pointer;
}
.rank__all i { font-style: normal; }
.rank__all:hover, .rank__all:focus-visible {
  background: var(--navy-soft);
  border-color: rgba(255, 255, 255, 0.5);
  color: var(--on-navy);
}

@media (max-width: 760px) {
  .card--glass { padding: 20px; border-radius: var(--r-m); }
  .board { padding: 20px; border-radius: var(--r-m); }
  .kpi__num { font-size: 30px; }
  /* На телефоне строка плана складывается: название и процент, под ними
     полоска, под ней пояснение во всю ширину — иначе «195 ₽ из 26 914 ₽»
     рвётся по слову на строку. */
  .plan__row { grid-template-columns: minmax(0, 1fr) 54px; row-gap: 8px; }
  /* Только в строке плана: ту же полоску носит карточка точки, и там она
     стоит сразу под процентом, а не в конце. */
  .plan__row > .plan__bar { grid-column: 1 / -1; order: 3; }
  .plan__row > .plan__tail { grid-column: 1 / -1; order: 4; }
}

/* ---------- полосы выполнения ---------- */

.bars { display: flex; flex-direction: column; gap: 11px; }
.bar-row {
  display: grid;
  grid-template-columns: minmax(120px, 1.1fr) minmax(0, 3fr) auto;
  align-items: center;
  gap: 14px;
  font-size: 15px;
}
.bar { height: 13px; border-radius: var(--r-pill); background: var(--surface); overflow: hidden; }
.bar > i { display: block; height: 100%; border-radius: var(--r-pill); background: var(--lime); }
.bar-row b { font-variant-numeric: tabular-nums; font-weight: 600; }

/* ---------- доли каналов ---------- */

.shares { display: flex; gap: 12px; align-items: stretch; min-height: 128px; }
.share {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 16px 18px;
  border-radius: var(--r-m);
  background: var(--card);
  border: 1px solid var(--line);
  min-width: 0;
}
.share--lead { background: var(--lime); border-color: var(--lime-deep); }
.share b { font-size: 22px; font-weight: 600; font-variant-numeric: tabular-nums; }
.share span { font-size: 15px; color: var(--muted); }
.share--lead span { color: #4a5a12; }

/* ---------- столбики по часам ---------- */

/* Без align-items: flex-end — иначе колонки сжимаются по содержимому, и
   проценты высоты столбика считаются от строки подписи, а не от 150px.
   Прижимает столбик вниз сама колонка через justify-content. */
.hours { display: flex; align-items: stretch; gap: 6px; height: 150px; }
.hour { flex: 1 1 0; display: flex; flex-direction: column; justify-content: flex-end; gap: 7px; min-width: 0; }
.hour i {
  display: block;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.22);
  min-height: 3px;
}
.hour--peak i { background: var(--lime); }
.hour span { font-size: 15px; text-align: center; color: var(--on-navy-dim); }

/*
 * Подсказка над столбиком. Нужна потому, что высота столбика отвечает
 * «больше или меньше», а вопрос у хозяина другой — «сколько именно».
 *
 * Столбик становится кнопкой клавиатуры (tabindex в разметке): подсказку
 * надо увидеть и с клавиатуры, а не только мышью.
 */
.hours { position: relative; }
.hour { position: relative; cursor: default; }
.hour i { position: relative; }
/* Подсказка висит над самим столбиком, а не над колонкой: у низкого часа
   цифра должна стоять там же, где его верхушка, иначе непонятно, к чему
   она относится. */
.hour i::after {
  content: attr(data-tip);
  position: absolute;
  left: 50%;
  bottom: 100%;
  transform: translate(-50%, -2px);
  margin-bottom: 4px;
  padding: 5px 9px;
  border-radius: 8px;
  background: #fff;
  color: var(--navy);
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .35);
  opacity: 0;
  pointer-events: none;
  transition: opacity .12s ease, transform .12s ease;
  z-index: 3;
}
.hour:hover i::after, .hour:focus-visible i::after { opacity: 1; transform: translate(-50%, -6px); }
/* Столбик под курсором светлеет: видно, к какому часу относится подсказка. */
.hour:hover i, .hour:focus-visible i { background: rgba(255, 255, 255, 0.4); }
.hour--peak:hover i, .hour--peak:focus-visible i { background: var(--lime); }
.hour:focus-visible { outline: none; }
/* Крайние часы: подсказка не должна уезжать за край панели. */
.hour:first-child i::after { left: 0; transform: translate(0, -2px); }
.hour:first-child:hover i::after, .hour:first-child:focus-visible i::after { transform: translate(0, -6px); }
.hour:last-child i::after { left: auto; right: 0; transform: translate(0, -2px); }
.hour:last-child:hover i::after, .hour:last-child:focus-visible i::after { transform: translate(0, -6px); }

/* ---------- списки и таблицы ---------- */

.rank { display: flex; flex-direction: column; gap: 8px; }
.rank .thumb { flex: 0 0 32px; }

.rank__item {
  display: grid;
  /* Номер, фото, название, сумма: фото помогает узнать позицию, не читая. */
  grid-template-columns: 30px 32px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-radius: 14px;
  background: var(--navy-soft);
}
.rank__num {
  width: 26px; height: 26px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.14);
  font-size: 14px;
}
.rank__name { min-width: 0; }
.rank__name b { display: block; font-weight: 500; font-size: 16px; }
.rank__name span { font-size: 15px; color: var(--on-navy-dim); }
.rank__sum { font-variant-numeric: tabular-nums; white-space: nowrap; }

.table-wrap { overflow-x: auto; }

/* Полоса прокрутки списка. По умолчанию система рисует её поверх строк, и в
   складе она ложилась на правый столбец: у «20 л» пропадала буква, у
   «0,96 кг» — единица измерения. Стоит задать полосе размер, и браузер
   перестаёт считать её накладной: она занимает место в строке, цифры встают
   левее, и накрывать их больше нечем. Полоса узкая и серая — в плотной
   таблице она подсказывает, что список длиннее окна. */
.table-wrap::-webkit-scrollbar, .spec::-webkit-scrollbar, .dlg__body::-webkit-scrollbar {
  width: 12px;
  height: 12px;
}
.table-wrap::-webkit-scrollbar-track, .spec::-webkit-scrollbar-track,
.dlg__body::-webkit-scrollbar-track { background: transparent; }
.table-wrap::-webkit-scrollbar-thumb, .spec::-webkit-scrollbar-thumb,
.dlg__body::-webkit-scrollbar-thumb {
  background: #c3cddd;
  border: 3px solid transparent;
  background-clip: content-box;
  border-radius: var(--r-pill);
}
.table-wrap::-webkit-scrollbar-thumb:hover, .spec::-webkit-scrollbar-thumb:hover,
.dlg__body::-webkit-scrollbar-thumb:hover { background: #a3b1c9; background-clip: content-box; }
/* На тёмной панели серая полоса читалась бы грязным пятном. */
.spec::-webkit-scrollbar-thumb, .spec .table-wrap::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.26);
  background-clip: content-box;
}
.spec::-webkit-scrollbar-thumb:hover, .spec .table-wrap::-webkit-scrollbar-thumb:hover {
  background: rgba(255, 255, 255, 0.44);
  background-clip: content-box;
}

/* Плотные списки мастер-детали: поля ячеек чуть у́же обычных — выигранные
   пиксели уходят единственной переносимой колонке. */
.card--pad0 th, .card--pad0 td { padding-left: 13px; padding-right: 13px; }
table { width: 100%; border-collapse: collapse; font-size: 15px; }
th, td { padding: 11px 16px; text-align: left; }
thead th {
  position: sticky; top: 0;
  background: var(--surface);
  font-size: 14px; font-weight: 600; color: #45526a;
  white-space: nowrap;
}
tbody tr + tr td { border-top: 1px solid var(--line); }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Дата, номер и плашка — короткие и неделимые: перенос их только ломает строку
   и делает высоту строк разной. Переносится одно название поставщика. */
td.nw, th.nw { white-space: nowrap; }
/* Выбираемая строка помечена aria-selected — по нему и цепляемся, иначе
   каждая новая таблица требовала бы своего атрибута в этом правиле. */
tbody tr[aria-selected] { cursor: pointer; }
tbody tr[aria-selected]:hover td { background: var(--surface); }
/* Выбор должен побеждать наведение: иначе под курсором фон светлеет, а текст
   остаётся белым, и выбранная строка исчезает. Отсюда двойной атрибут —
   специфичность выше, чем у :hover. */
tbody tr[aria-selected][aria-selected="true"] td,
tbody tr[aria-selected][aria-selected="true"]:hover td {
  background: var(--navy);
  color: var(--on-navy);
}
tbody tr[aria-selected="true"] td:first-child { border-radius: 10px 0 0 10px; }
tbody tr[aria-selected="true"] td:last-child { border-radius: 0 10px 10px 0; }
tbody tr[aria-selected="true"] .muted { color: var(--on-navy-dim); }

.tag {
  display: inline-block;
  padding: 3px 11px;
  border-radius: var(--r-pill);
  background: var(--surface);
  /* Цвет задан явно: в выбранной строке текст наследовал бы белый от тёмного
     фона строки и становился белым по светлой плашке. */
  color: #45526a;
  font-size: 15px;
  white-space: nowrap;
}
.tag--good { background: #e7f2d8; color: #2f5119; }
.tag--warn { background: #f7e4d6; color: #5f2d07; }
/* Точка. Не статус и не оценка — только адрес строки, поэтому тише прочих. */
.tag--venue { background: #eef1f6; color: #45526a; font-size: 14px; padding: 2px 9px; }
.tag--lime { background: var(--lime); color: var(--ink); font-weight: 600; }

/* ---------- техкарта ---------- */

/* Список позиций длинный, а техкарта нужна всё время: прилепляем её, иначе
   при прокрутке справа остаётся пустая синяя полоса. */
.spec {
  position: sticky;
  top: 16px;
  align-self: start;
  max-height: calc(100dvh - 32px);
  overflow-y: auto;
}
.spec__head { display: flex; align-items: center; gap: 12px; margin-bottom: 4px; }
.spec__head h3 { margin: 0; font-size: 26px; font-weight: 600; letter-spacing: -0.01em; }
.spec table { font-size: 15px; }
.spec thead th { background: none; color: var(--on-navy-dim); border-bottom: 1px solid rgba(255, 255, 255, 0.16); }
.spec tbody tr + tr td { border-top: 1px solid rgba(255, 255, 255, 0.09); }
/* Поля в панели у́же, чем в большой таблице: четыре столбца техкарты с полями
   по десять пикселей не помещались в панель, и состав блюда получал
   горизонтальную прокрутку ради трёх лишних пикселей. */
.spec td { padding: 9px 8px; }
.spec th { padding: 8px 8px; }

.spec__totals { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; margin-top: 18px; }
.spec__cell { padding: 13px 16px; border-radius: 14px; background: var(--navy-soft); }
.spec__cell span { display: block; font-size: 15px; color: var(--on-navy-dim); }
.spec__cell b { font-size: 21px; font-weight: 600; font-variant-numeric: tabular-nums; }
.spec__cell--lime { background: var(--lime); color: var(--ink); }
.spec__cell--lime span { color: #4a5a12; }

/* Откуда заказы: доля, название, сумма и полоска. Таблицей это читалось бы
   хуже — глаз сравнивает длины, а не числа. */
.srcs { display: flex; flex-direction: column; gap: 14px; }
.src {
  display: grid;
  grid-template-columns: 68px minmax(0, 1fr) auto;
  grid-template-areas: 'pct name sum' 'pct bar bar';
  align-items: center;
  gap: 2px 12px;
}
.src > b { grid-area: pct; font-size: 22px; font-weight: 600;
  font-variant-numeric: tabular-nums; white-space: nowrap; }
.src__name { grid-area: name; font-size: 16px; font-weight: 500; }
.src__sum { grid-area: sum; font-size: 15px; color: var(--muted); white-space: nowrap; }
.src__bar { grid-area: bar; height: 8px; border-radius: 999px; background: var(--line); overflow: hidden; }
.src__bar i { display: block; height: 100%; border-radius: 999px; background: var(--navy); }

/* ---------- состояния ---------- */

.empty { padding: 46px 22px; text-align: center; color: var(--muted); }
.empty p { margin: 0 auto; max-width: 440px; }
.empty p + p { margin-top: 8px; }

/* Список позиций внутри панели ограничен по высоте. Без этого накладная на
   36 позиций растягивает панель вчетверо против накладной на одну, и всё, что
   под ней, подпрыгивает при каждом выборе строки. */
.spec .table-wrap { max-height: 46dvh; overflow-y: auto; }

/* Две колонки — две прокрутки. Список и карточка прилипают к верху и крутятся
   каждый свой, не задевая соседа: иначе колесо над карточкой уносит список, и
   выбранная строка уезжает из виду.
   Докрутив до конца, колесо продолжает страницу, а не глохнет. Раньше здесь
   стоял `overscroll-behavior: contain`, и прокрутка упиралась в стену посреди
   экрана: инерция тачпада гасла, страница не ехала, и это читалось как
   подвисание. Удержание оставлено модальному окну, где за ним и правда ничего
   не должно двигаться. */
.row--split--list > .card--pad0 { position: sticky; top: 16px; align-self: start; }
.row--split--list > .card--pad0 > .table-wrap {
  max-height: calc(100dvh - 32px);
  overflow-y: auto;
}

/* Место под полосу прокрутки держим всегда — в тех списках, где высота
   ограничена и полоса то нужна, то нет. Переключили фильтр, строк стало
   меньше экрана, полоса пропала — и без этой строчки таблица прыгала бы
   вправо на её ширину. Там, где таблица показана целиком, пустой колеи
   справа быть не должно, поэтому правило не общее. В тёмной панели и в окне
   колеи нет: там списки короткие, полоса появляется редко, и пустые
   двенадцать пикселей справа были бы заметнее, чем сам скачок. */
.row--split--list > .card--pad0 > .table-wrap { scrollbar-gutter: stable; }

/* Список складывается в столбик раньше, чем остальная мастер-деталь: самой
   широкой таблице склада — накладным — нужно 650 пикселей, и в колонке
   1,68fr она упирается в этот предел уже около 1150. Дальше браузер начинает
   резать правый столбец, а не ужимать его: «0,96 кг» теряет единицы. */
@media (max-width: 1200px) {
  .row--split--list { grid-template-columns: minmax(0, 1fr); }
  .row--split--list > .card--pad0 { position: static; }
  .row--split--list > .card--pad0 > .table-wrap { max-height: min(52dvh, 460px); }
  .row--split--list .spec { position: static; max-height: none; overflow: visible; }
  .row--split--list .spec .table-wrap { min-height: 150px; max-height: 260px; overflow-y: auto; }
}

@media (max-width: 1100px) {
  /* Ниже этой ширины мастер-деталь складывается в столбик. «Липкая» панель с
     собственной прокруткой здесь становится ловушкой: страница прокручивается,
     панель прилипает к верху и забирает колесо себе. В столбик — обычным
     блоком. */
  .row--split { grid-template-columns: minmax(0, 1fr); }
  .spec { position: static; max-height: none; overflow: visible; }
  /* Список слева получает свою высоту и свою прокрутку, иначе деталь выбранной
     строки уезжает под низ пятнадцати строк и щелчок выглядит безответным. */
  .card--pad0 > .table-wrap { max-height: min(52dvh, 460px); overflow-y: auto; }
  .row--split--list > .card--pad0 { position: static; }
  .row--split--list > .card--pad0 > .table-wrap { max-height: min(52dvh, 460px); }
  /* Нижняя граница — чтобы накладная на одну позицию не схлопывала панель и
     всё под ней не подпрыгивало при переборе строк. Верхняя — чтобы накладная
     на три десятка не растягивала её на пол-экрана. */
  .spec .table-wrap { min-height: 150px; max-height: 260px; overflow-y: auto; }
}
@media (max-width: 860px) {
  .topbar { flex-wrap: wrap; }
  .tabs { order: 3; width: 100%; overflow-x: auto; flex-wrap: nowrap; }
  .topbar__end { margin-left: auto; }
  .shares { flex-direction: column; }
  .bar-row { grid-template-columns: minmax(0, 1fr) auto; }
  .bar-row .bar { grid-column: 1 / -1; }
}

/* ---------- подразделы и фильтры ---------- */

.subbar { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-bottom: 14px; }
.subbar__end { margin-left: auto; display: flex; flex-wrap: wrap; gap: 10px; }
/* Шапка внутри карточки с таблицей. У карточки полей нет — они у ячеек, —
   и заголовок без этого правила лежит вплотную к краю, а столбец под ним
   с отступом: строка выглядит сдвинутой. */
.card--pad0 > .subbar { padding: 16px 13px 0; }
.seg--tabs button[aria-pressed="true"] { background: var(--lime); color: var(--ink); }

.filters { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px; }
.filters__count { font-size: 15px; }
/* Действие над списком — у правого края той же строки, где фильтры: оно
   про этот список, а не про весь раздел. */
.filters__act { margin-left: auto; }

/* Плюс в заголовке папки: добавить позицию сразу в неё. Квадратная
   кнопка без подписи — в строке папки на подпись места нет, а смысл
   у плюса рядом с названием папки один. */
.grp__add {
  flex: 0 0 auto;
  width: 28px; height: 28px;
  display: grid; place-items: center;
  border: 1px solid var(--line); border-radius: 9px;
  background: var(--card); color: var(--ink);
  font-size: 17px; line-height: 1; cursor: pointer;
}
.grp__add:hover { background: var(--lime); border-color: var(--lime); }

/* ---------- кнопки ---------- */

.btn--ghost { background: var(--card); color: var(--ink); border: 1px solid var(--line); }
.btn--ghost i { background: var(--surface); color: var(--ink); }
.btn--ghost:hover { background: var(--surface); }
/* Кнопка внутри тёмной панели: салатовая там спорила бы с акцентом панели. */
.btn--onnavy { background: rgba(255, 255, 255, 0.13); color: var(--on-navy); }
.btn--onnavy i { background: rgba(255, 255, 255, 0.2); color: var(--on-navy); font-size: 14px; }
.btn--onnavy:hover { background: rgba(255, 255, 255, 0.22); }
.btn--danger { background: #6b1d0d; color: #fff; }
.btn--danger i { background: #fff; color: #6b1d0d; }
.btn--sm { min-height: 38px; padding: 6px 8px 6px 16px; font-size: 15px; }
.btn--sm i { width: 24px; height: 24px; font-size: 14px; }

.icon-btn {
  width: 44px; height: 44px; flex: 0 0 44px;
  display: grid; place-items: center;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  color: #45526a;
  font: inherit;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}
.icon-btn:hover { background: var(--surface); color: var(--ink); }

/* ---------- состояние оплаты ---------- */

/* Цвета подобраны расчётом APCA: каждая пара держит Lc не ниже 80, поэтому
   плашке хватает 15px. На 14px того же контраста было бы мало — там нужно
   уже Lc 90, и подписи пришлось бы делать почти чёрными. */
.pay {
  display: inline-block;
  padding: 3px 11px;
  border-radius: var(--r-pill);
  font-size: 15px;
  font-weight: 500;
  white-space: nowrap;
}
.pay--paid { background: #e7f2d8; color: #2f5119; }
.pay--partial, .pay--soon { background: #fae8cd; color: #5f2d07; }
.pay--overdue { background: #f8e0db; color: #6b1d0d; font-weight: 600; }
.pay--due { background: var(--lime); color: var(--ink); font-weight: 600; }
.pay--planned, .pay--unknown { background: var(--surface); color: #45526a; }
.tag--hole { background: #faeade; color: #5f2d07; }

/* ---------- шкала запаса ---------- */

/* Вся полоса — месячный расход, залитая часть — то, что лежит на складе.
   Полная полоса значит «запаса больше чем на месяц». */
.gauge {
  display: block;
  width: 100%;
  min-width: 56px;
  height: 7px;
  margin-top: 5px;
  border-radius: var(--r-pill);
  background: var(--line);
  overflow: hidden;
}
.gauge > i { display: block; height: 100%; border-radius: var(--r-pill); background: var(--muted); }
.gauge--paid > i { background: #5f9a3f; }
.gauge--soon > i { background: #a97410; }
.gauge--due > i, .gauge--overdue > i { background: #c0452a; }
.gauge--idle > i { background: var(--line); }
/* Оценка штрихуется: по виду сразу ясно, что цифра посчитана, а не пересчитана. */
.gauge--est > i {
  background-image: repeating-linear-gradient(
    115deg, rgba(255, 255, 255, 0.55) 0 4px, transparent 4px 9px);
}
/* Пустая полоса с красноватой подложкой читается как «ничего не осталось»,
   а не как «шкала не нарисовалась». */
.gauge--overdue { background: #f3d2ca; }
.below { color: #6b1d0d; }
tbody tr[aria-selected="true"] .below { color: #f7cfc5; }
.gauge--unknown { background: repeating-linear-gradient(90deg, var(--line) 0 5px, transparent 5px 10px); }

tbody tr[aria-selected="true"] .gauge { background: rgba(255, 255, 255, 0.2); }
tbody tr[aria-selected="true"] .gauge--unknown {
  background: repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.3) 0 5px, transparent 5px 10px);
}

/* Та же шкала в тёмной панели, крупнее. */
.stock { margin-bottom: 18px; }
.stock__scale .gauge { height: 14px; margin: 0; background: rgba(255, 255, 255, 0.16); }
.stock__marks {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin-top: 7px;
  font-size: 15px;
  color: var(--on-navy-dim);
}
.stock__marks span:first-child { color: var(--on-navy); font-weight: 600; }
.stock__says { margin: 14px 0 0; font-size: 16px; }
.stock__basis { margin: 8px 0 0; font-size: 15px; color: var(--on-navy-dim); }
.stock__says .pay { margin-right: 8px; vertical-align: 1px; }

/* ---------- ссылка внутри строки таблицы ---------- */

.lnk {
  background: none; border: none; padding: 0;
  font: inherit; color: inherit; text-align: left; cursor: pointer;
  text-decoration: underline;
  text-decoration-color: var(--line);
  text-underline-offset: 3px;
}
.lnk:hover { text-decoration-color: currentColor; }

/* ---------- группировка в таблице ---------- */

tbody tr.grp td {
  background: var(--surface);
  cursor: pointer;
  padding-top: 14px;
  padding-bottom: 14px;
}
tbody tr.grp:hover td { background: #eaeef5; }
tbody tr.grp + tr td { border-top: none; }

/* Папка — не строка списка, а его заголовок: своя полоса, жирнее и темнее.
   Линия сверху отбивает её от содержимого предыдущей папки. */
.menu-list tbody tr.grp td {
  background: #e7ecf4;
  border-top: 2px solid var(--navy);
  font-size: 17px;
}
.menu-list tbody tr.grp:first-child td { border-top: none; }
/* Заголовок папки занимает всю ширину и не считается с колонками списка:
   иначе «Холодные роллы — классика» ломается надвое ради колонки с ценой.
   Flex живёт внутри ячейки, а не на ней: на самой ячейке он отменил бы
   display: table-cell, и colspan перестал бы действовать. */
.grp__bar { display: flex; align-items: center; gap: 10px; }

/* Папка, которой под текущим фильтром нечего показать. Остаётся в списке,
   но приглушена: видно, что она цела и ничего не пропало. */
tbody tr.grp--off td { color: var(--muted); font-weight: 400; }
.grp__bar .grp__name { flex: 0 1 auto; }
.grp__bar .grp__live { margin-left: auto; }
.grp__bar .nw { white-space: nowrap; }

@media (max-width: 860px) {
  /* На телефоне заголовок в строку не влезает. Переносим целыми словами:
     название на первой строке, счётчики и «настроить» — на второй. */
  .grp__bar { flex-wrap: wrap; row-gap: 4px; }
  .grp__bar .grp__name { flex: 1 0 auto; }
  .grp__bar .grp__live { margin-left: 0; }
  /* Плюс переезжает на вторую строку — прижимаем его к правому краю,
     иначе он встаёт под названием папки и читается как часть заголовка. */
  .grp__bar .grp__add { margin-left: auto; }
}
.menu-list tbody tr.grp:hover td { background: #dde4ef; }
.menu-list tbody tr.grp .grp__name { cursor: pointer; }
.menu-list tbody tr.grp--shut td { border-bottom: 1px solid var(--line); }

/* Треугольник раскрытия. Рисуем бордерами, чтобы не тянуть иконочный шрифт
   ради одной стрелки. */
.grp__fold {
  flex: 0 0 24px;
  width: 24px;
  height: 24px;
  padding: 0;
  border: none;
  border-radius: 7px;
  background: transparent;
  cursor: pointer;
  position: relative;
}
.grp__fold::before {
  content: '';
  position: absolute;
  inset: 0;
  margin: auto;
  width: 0;
  height: 0;
  border-left: 6px solid var(--navy);
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  transform: rotate(90deg);
  transform-origin: 3px 50%;
  transition: transform 0.12s ease;
}
.grp__fold[aria-expanded="false"]::before { transform: rotate(0deg); }
.grp__fold:hover { background: rgba(23, 33, 61, 0.09); }
.grp__fold:focus-visible { outline: 2px solid var(--navy); outline-offset: 1px; }

/* ---------- факты в тёмной панели ---------- */

.facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px 18px;
  margin: 0 0 18px;
}
.facts > div { min-width: 0; }
.facts dt { margin: 0; font-size: 15px; color: var(--on-navy-dim); }
.facts dd { margin: 2px 0 0; font-size: 16px; }
/* Не .wrap: так называется контейнер страницы, и его padding достался бы
   значению реквизита отступом в 28 пикселей. */
.facts dd.long { word-break: break-word; }
.facts .none { color: var(--on-navy-dim); }
.facts a { color: var(--lime); text-underline-offset: 3px; }

.spec__sub { margin: 0 0 16px; }
.spec__h { margin: 22px 0 10px; font-size: 16px; font-weight: 600; letter-spacing: -0.01em; }
.spec__note { margin: 12px 0 0; font-size: 15px; color: var(--on-navy-dim); }
.spec__acts { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
/* Кнопки действий в панели у́же обычных: панель — колонка, а не страница, и
   три кнопки в полный размер в ней не становятся в ряд. Высота остаётся 44. */
.spec__acts .btn { padding: 9px 9px 9px 16px; font-size: 15px; gap: 8px; }
.spec__acts .btn i { width: 24px; height: 24px; font-size: 14px; }

/* ---------- модальная форма ---------- */

dialog.dlg {
  border: none;
  padding: 0;
  margin: auto;
  width: min(720px, calc(100vw - 24px));
  max-height: calc(100dvh - 32px);
  border-radius: var(--r-l);
  background: var(--card);
  color: var(--ink);
  box-shadow: 0 40px 90px -40px rgba(15, 26, 51, 0.55);
}
dialog.dlg--wide { width: min(960px, calc(100vw - 24px)); }
dialog.dlg::backdrop { background: rgba(15, 26, 51, 0.5); }

.dlg__form {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 22px 24px calc(20px + env(safe-area-inset-bottom));
  max-height: calc(100dvh - 32px);
}
.dlg__head { display: flex; align-items: center; gap: 14px; }
.dlg__head h3 { margin: 0; font-size: 24px; font-weight: 600; letter-spacing: -0.01em; }
.dlg__head .icon-btn { margin-left: auto; }
.dlg__note { margin: 0; font-size: 15px; }
/* Скролл только у середины: заголовок и кнопки должны оставаться на месте,
   иначе в длинной форме кнопку «сохранить» приходится искать прокруткой. */
.dlg__body { min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column; gap: 18px; }
.dlg__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 14px; }
/* Действия над самой записью («больше не платим», «удалить») стоят рядом, а
   не двумя полосами во всю ширину окна: во всю ширину они спорят весом с
   «Сохранить», хотя нужны реже. */
.dlg__acts { display: flex; flex-wrap: wrap; gap: 10px; }
.fld-wrap--wide { grid-column: span 2; }
.fld-sec { grid-column: 1 / -1; margin: 8px 0 0; font-size: 15px; font-weight: 600; color: #45526a; }

/* Окно «Все позиции»: переключатель сортировки, под ним таблицы блюд и
   дополнений. Шапка таблицы липкая сама по себе — прокручивается тело окна. */
.pos { display: flex; flex-direction: column; gap: 10px; }
.pos .fld-sec { margin: 10px 0 0; }
.pos table { font-size: 15px; }
/* Своя прокрутка у каждой таблицы: в списке на восемь десятков строк шапка
   должна оставаться на экране — без неё четыре колонки цифр не различить.
   Липкой шапке нужен свой прокручиваемый ящик, иначе она уезжает вместе с
   таблицей. */
.pos .table-wrap { max-height: 46vh; overflow-y: auto; }
/* На телефоне шесть колонок не влезают: с ними «110 311 ₽» уезжает за край,
   и список приходится возить вбок. Оставляем три — название, порции и
   выручку: по ним и смотрят, что берут. Прибыль, раздел меню и число
   заказов видны на экране пошире. */
@media (max-width: 700px) {
  .pos .pos__cat, .pos .pos__ord, .pos .pos__mrg { display: none; }
  .pos table { font-size: 14px; }
  .pos th, .pos td { padding-left: 7px; padding-right: 7px; }
  /* Длинному названию разрешено переноситься хоть посреди слова: иначе
     «Калифорния» держит колонку шире, чем есть место, и «1 920 401 ₽» в
     итоге обрезается на середине цифры. */
  .pos th:first-child, .pos td:first-child { overflow-wrap: anywhere; }
}
/* Итог отбит линией и не уезжает при прокрутке: по нему сверяют сумму,
   не возвращаясь в конец списка. */
.pos tfoot td {
  position: sticky;
  bottom: 0;
  background: var(--card);
  border-top: 2px solid var(--line);
  font-weight: 600;
}
.fld-wrap label { display: block; margin-bottom: 5px; font-size: 15px; color: #45526a; }
.req-mark { color: #6b1d0d; font-style: normal; }
.fld-hint { margin: 5px 0 0; font-size: 15px; color: #45526a; }

/* Короткая инструкция в окне. Нужна там, где дело делается не только в
   учёте: контур зоны рисуют в чужой карте, и шаги, рассказанные в чате,
   к следующему разу забудутся — а окно останется. */
.howto {
  margin: 12px 0 0;
  padding: 12px 14px;
  border-radius: var(--r-md, 12px);
  background: #f3f5f9;
  font-size: 15px;
  color: #45526a;
}
.howto > b { color: var(--navy, #1b2a4a); }
.howto ol { margin: 6px 0 0; padding-left: 20px; }
.howto li { margin: 4px 0; }
.howto p { margin: 8px 0 0; }
.howto__k { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 14px; }

.fld {
  width: 100%;
  min-height: 44px;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  color: var(--ink);
  font: inherit;
  /* 16px не случайно: на меньшем размере Safari на iPhone зумит страницу при
     попадании в поле, и форма уезжает за край. */
  font-size: 16px;
}
.fld--area { min-height: 76px; resize: vertical; }
.fld.num { text-align: right; font-variant-numeric: tabular-nums; }
/* Единица короткая — поля по бокам только съедают место под «шт». */
.items__row .fld[data-k="unit"] { padding-left: 8px; padding-right: 8px; text-align: center; }
.fld::placeholder { color: #7d8799; }
/* Поля, которых у строки нет: у строки-блюда ни брутто, ни отхода — они
   посчитаны внутри её собственной техкарты. Поле видно, но не правится:
   убрать его совсем значило бы сломать колонки у соседних строк. */
.fld:disabled { border-style: dashed; background: var(--surface); color: #7d8799; }

/* Дни смены. Галочка лежит поверх кнопки и не видна: нажимают по всей
   плашке, а не по квадратику шесть на шесть миллиметров. */
.days { display: flex; flex-wrap: wrap; gap: 8px; }
.day-chip { position: relative; display: block; }
.day-chip .fld {
  position: absolute; inset: 0; width: 100%; height: 100%; min-height: 0;
  margin: 0; padding: 0; opacity: 0; cursor: pointer;
}
.day-chip span {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-width: 56px; min-height: 56px; padding: 6px 10px;
  border: 1px solid var(--line); border-radius: 12px;
  background: var(--card); color: var(--muted); line-height: 1.2;
}
.day-chip b { font-size: 15px; font-weight: 600; }
.day-chip i { font-style: normal; font-size: 14px; }
.day-chip .fld:checked + span {
  background: var(--navy); border-color: var(--navy); color: var(--on-navy);
}
.day-chip .fld:focus-visible + span { outline: 2px solid var(--navy); outline-offset: 2px; }
/* На этом дне смена уже стоит — отметишь, и она заменится. */
.day-chip--busy span::after {
  content: ''; width: 5px; height: 5px; margin-top: 4px;
  border-radius: 50%; background: var(--lime);
}

.fld-check { display: flex; align-items: center; gap: 11px; min-height: 44px; font-size: 16px; }
.fld-check .fld {
  width: 22px; height: 22px; min-height: 22px; flex: 0 0 22px;
  padding: 0; accent-color: var(--navy);
}

.items { display: flex; flex-direction: column; gap: 8px; }
.items__head, .items__row {
  display: grid;
  grid-template-columns: minmax(0, 2.4fr) 88px 74px 108px minmax(80px, 1fr) 44px;
  gap: 8px;
  align-items: center;
}
.items--plain .items__head, .items--plain .items__row {
  grid-template-columns: minmax(0, 2.4fr) 88px 74px 44px;
}
.items--nounit .items__head, .items--nounit .items__row {
  grid-template-columns: minmax(0, 2.4fr) 110px 44px;
}
/* Техкарта: цена своя, из номенклатуры, поэтому колонки цены нет — а сумма
   есть, иначе не видно, что закладка делает с фудкостом. */
.items--cost .items__head, .items--cost .items__row {
  grid-template-columns: minmax(0, 2.4fr) 110px minmax(80px, 1fr) 44px;
}
/* Техкарта с отходом: брутто — отход — нетто — сумма. */
.items--trim .items__head, .items--trim .items__row {
  grid-template-columns: minmax(0, 1.9fr) 88px 76px 88px minmax(74px, 1fr) 44px;
}
/* То же с колонкой единицы: её не вписывают, она приходит от продукта. */
.items--unitro.items--trim .items__head, .items--unitro.items--trim .items__row {
  grid-template-columns: minmax(0, 1.6fr) 92px 70px 90px 46px minmax(66px, 1fr) 44px;
}
.items__unit { font-size: 15px; color: #45526a; text-align: center; }
/* Подпись поля нужна только там, где шапки таблицы нет. */
.items__f { display: block; min-width: 0; position: relative; }
/* У строки-блюда количество — порции, а не граммы, и шапка таблицы про это
   не знает: она одна на все строки. Поэтому единица стоит в самой строке,
   прижатая к правому краю поля. */
.items__row[data-whole] .items__f[data-cell="qty"]::after {
  content: 'порц.';
  position: absolute;
  right: 12px;
  bottom: 0;
  display: flex;
  align-items: center;
  height: 44px;
  font-size: 13px;
  color: #7d8799;
  pointer-events: none;
}
.items__row[data-whole] [data-k="qty"] { padding-right: 46px; }
.items__f > span { display: none; }
.items__f .fld { width: 100%; }

@media (max-width: 720px) {
  /* На телефоне строка складывается: название во всю ширину, под ним три
     числа с подписями, ещё ниже сумма и крестик. */
  .items--trim .items__head { display: none; }
  .items--trim .items__row { grid-template-columns: repeat(3, minmax(0, 1fr)); row-gap: 10px; }
  .items--trim .items__row > .fld[data-k="name"] { grid-column: 1 / -1; }
  .items--trim .items__row .items__sum { grid-column: 1 / 3; text-align: left; align-self: center; }
  .items--trim .items__row [data-del] { justify-self: end; }
  .items--unitro.items--trim .items__row { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* Здесь единицу говорит подпись поля — отдельная колонка была бы лишней. */
  .items--unitro .items__unit { display: none; }
  .items__f > span { display: block; margin-bottom: 3px; font-size: 13px; color: #45526a; }
  /* Здесь единицу говорит подпись строки — второй раз в самом поле не надо. */
  .items__row[data-whole] .items__f[data-cell="qty"]::after { display: none; }
  .items__row[data-whole] [data-k="qty"] { padding-right: 14px; }
}

/* Отход рядом с брутто: «35,1 −43%». Мелко и приглушённо — это пояснение
   к числу, а не ещё одна колонка. */
.recipe__waste { font-size: 13px; color: var(--on-navy-dim); }
/* Порции у строки-блюда: «Филадельфия ×2». Количество стоит у названия, а
   колонки остаются граммами — тогда итог складывается без оговорок. */
.recipe__mult { margin-left: 6px; font-size: 13px; color: var(--on-navy-dim); }
/* Брутто под названием нужно только там, где для него нет колонки. */
.recipe__brutto { display: none; font-size: 13px; color: var(--on-navy-dim); }
@media (max-width: 860px) { .recipe__brutto { display: block; } }
/* Шапка держится наверху списка: строк в техкарте бывает два десятка, и,
   дописывая закладку внизу, перестаёшь помнить, какое окошко — брутто, какое
   отход, а какое то, что попадёт в блюдо. */
.items__head {
  position: sticky;
  top: 0;
  z-index: 2;
  padding-block: 6px;
  background: var(--card);
  font-size: 15px;
  color: #45526a;
}
.items__head .num { text-align: right; }
.items__sum { text-align: right; font-size: 16px; font-variant-numeric: tabular-nums; }
.items__foot {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px 14px;
  padding-top: 10px; border-top: 1px solid var(--line);
}
.items__tally {
  margin-left: auto; display: flex; align-items: baseline; flex-wrap: wrap;
  justify-content: flex-end; gap: 4px 14px;
}
.items__total { font-size: 16px; }
.items__total b { font-size: 20px; font-variant-numeric: tabular-nums; }
.items__mass { font-size: 15px; color: #45526a; }
.items__mass b { font-weight: 600; color: var(--navy); font-variant-numeric: tabular-nums; }
.items__blind { color: var(--warn); }
.items__hint { margin: 0; font-size: 15px; }

/* ---------- разбор загруженной накладной ---------- */

.fld--file { padding: 9px 12px; line-height: 24px; }
.fld--file::file-selector-button {
  margin-right: 12px;
  min-height: 30px;
  padding: 4px 14px;
  border: none;
  border-radius: var(--r-pill);
  background: var(--navy);
  color: var(--on-navy);
  font: inherit;
  font-size: 15px;
  cursor: pointer;
}

.imp { display: flex; flex-direction: column; gap: 6px; }
.imp__head, .imp__fields {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 84px 66px 96px 104px 44px;
  gap: 8px;
  align-items: center;
}
.imp__head { font-size: 15px; color: #45526a; padding: 0 8px; }
.imp__head .num { text-align: right; }

.imp__row { padding: 6px 8px; border-radius: 12px; }
/* Жёлтым помечено то, в чём разбор не уверен: похожее имя, неверная
   арифметика, непонятная единица. Цвет гаснет, как только строку поправили. */
.imp__row--check { background: #fdf4df; }
.imp__raw { margin: 0 0 5px; font-size: 15px; }
.imp__why { display: block; font-size: 15px; color: #5f2d07; }
.imp__row:not(.imp__row--check) .imp__why { color: #45526a; }
/* Сумма строки стала полем: её правят так же, как цену, — в накладной
   поставщика написана именно она, а цена за килограмм выходит делением. */
.imp__fields .fld[data-k="sum"] { text-align: right; }
.imp__row[hidden] { display: none; }

.imp__foot {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 8px 0;
  border-top: 1px solid var(--line);
}
.imp__count { font-size: 15px; color: #5f2d07; }
.imp__count--ok { color: #2f5119; }
.imp__foot .items__total { margin-left: auto; }

/* Список прикреплённых документов в тёмной панели. */
.docs { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.docs__item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto 36px;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-radius: 12px;
  background: var(--navy-soft);
}
.docs__item a { color: var(--lime); text-underline-offset: 3px; word-break: break-word; }
.docs__meta { font-size: 15px; color: var(--on-navy-dim); white-space: nowrap; }
.icon-btn--sm {
  width: 36px; height: 36px; flex: 0 0 36px;
  background: rgba(255, 255, 255, 0.12);
  border-color: transparent;
  color: var(--on-navy-dim);
  font-size: 18px;
}
.icon-btn--sm:hover { background: rgba(255, 255, 255, 0.2); color: var(--on-navy); }

/* Что удалось вычитать из прикреплённого документа. */
.imp__read {
  margin: 0;
  padding: 11px 14px;
  border-radius: 12px;
  background: var(--surface);
  color: #45526a;
  font-size: 15px;
}
.imp__read--ok { background: #e7f2d8; color: #2f5119; }
.imp__read--warn { background: #fdf4df; color: #5f2d07; }

.imp__warn, .imp__new {
  margin: 0;
  padding: 11px 14px;
  border-radius: 12px;
  font-size: 15px;
}
.imp__warn { background: #f8e0db; color: #6b1d0d; }
.imp__new { background: #e7f2d8; color: #2f5119; }

/* Карточка поставщика: что из документа ляжет в справочник. */
.imp__card {
  padding: 12px 14px;
  border-radius: 12px;
  background: #e7f2d8;
  color: #2f5119;
}
.imp__card-head { margin: 0 0 6px; font-size: 15px; font-weight: 600; }
.imp__card .fld-check { min-height: 34px; font-size: 15px; }
.imp__card .fld-check b { font-weight: 600; word-break: break-word; }
/* Расхождение с тем, что уже записано, — тот же жёлтый, что и у позиций. */
.imp__card .imp__conflict {
  margin: 4px -8px;
  padding: 4px 8px;
  border-radius: 10px;
  background: #fdf4df;
  color: #5f2d07;
}
.imp__was { display: block; font-size: 15px; color: #5f2d07; }

/* ---------- тумблер «видно на сайте» ---------- */

.sw {
  display: inline-flex;
  align-items: center;
  width: 42px;
  height: 24px;
  flex: 0 0 42px;
  margin-right: 10px;
  padding: 3px;
  border: none;
  border-radius: var(--r-pill);
  background: #c3cbd8;
  cursor: pointer;
  vertical-align: -6px;
}
.sw i { width: 18px; height: 18px; border-radius: 50%; background: #fff; transition: transform .12s; }
.sw--on { background: var(--good); }
.sw--on i { transform: translateX(18px); }
@media (prefers-reduced-motion: reduce) { .sw i { transition: none; } }
tbody tr[aria-selected="true"] .sw { background: rgba(255, 255, 255, 0.35); }
tbody tr[aria-selected="true"] .sw--on { background: #7ec45a; }

/* Миниатюра в строке — ровно по высоте строки: она помогает узнать позицию,
   а не разглядывать её. Ячейка от этого не должна становиться выше. */
.menu-list .c-sup, .pic-cell { display: flex; align-items: center; gap: 10px; }
.menu-list .c-sup > span, .pic-cell > span { min-width: 0; }
.thumb {
  flex: 0 0 32px;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  object-fit: cover;
  background: var(--line);
}
.thumb--none {
  display: block;
  border: 1px dashed var(--line);
  background: transparent;
}
tbody tr[aria-selected="true"] .thumb--none { border-color: rgba(255, 255, 255, 0.3); }
.menu-list .c-sup .sw { margin-right: 0; }

/* Выключенное видно, но приглушено: оно есть в учёте, просто не на сайте. */
.row--off td { opacity: 0.55; }
tbody tr.grp--off td { opacity: 0.6; }

/* ---------- карточка блюда ---------- */

.dish__photo {
  margin: 0 0 14px;
  border-radius: var(--r-m);
  overflow: hidden;
  background: var(--navy-soft);
}
.dish__photo img { display: block; width: 100%; height: auto; }
.dish__text { margin: 0 0 4px; font-size: 16px; }
.dish__list { margin: 0; padding-left: 20px; font-size: 16px; }
.dish__list li + li { margin-top: 3px; }
/* Техкарта длинная и прокручивается внутри себя. Шапка и итог прилипают:
   иначе на двадцатой строке уже не видно, что за колонки, и ради суммы,
   ради которой всё и смотрят, приходится крутить до конца. */
/* Техкарта длиннее панели накладной: двадцать строк в окошке на три читать
   нечем. Отдаём ей половину экрана, итог всё равно прилипший. */
.spec [data-recipe] .table-wrap { min-height: 0; max-height: min(50dvh, 440px); }
.recipe thead th { position: sticky; top: 0; z-index: 1; background: var(--navy); }
.recipe tfoot td {
  position: sticky;
  bottom: 0;
  background: var(--navy-soft);
  border-top: 1px solid rgba(255, 255, 255, 0.18);
}

.spec__totals--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* Четыре ячейки в ряд вместо трёх: при общих отступах «Углеводы» — самое
   длинное слово в КБЖУ — не влезает в свою ячейку и обрезается. Сужаем поля
   и подпись только в этом варианте, в трёхколоночном всё и так помещается. */
.spec__totals--4 .spec__cell { padding: 13px 10px; }
.spec__totals--4 .spec__cell span { font-size: 13px; }
@media (max-width: 680px) { .spec__totals--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* ---------- список подсказок ---------- */

/* Свой, а не родной <datalist>: тот внутри модального окна в части браузеров
   не всплывает или рисуется поверх соседних полей.
   Списку нужен блок, от которого считать координаты, но задавать окну
   position: relative НЕЛЬЗЯ. Модальному окну браузер сам ставит fixed,
   а relative возвращает его в поток документа: окно оказывается у начала
   страницы, и браузер туда же прокручивает — открыл карточку, а список
   уехал наверх. Блок для отсчёта даёт и fixed, так что ничего задавать
   не нужно. */
.combo {
  position: absolute;
  z-index: 5;
  margin: 0;
  padding: 4px;
  list-style: none;
  max-height: 232px;
  overflow-y: auto;
  border-radius: 14px;
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: 0 18px 40px -18px rgba(15, 26, 51, 0.45);
}
.combo li {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 9px 12px;
  border-radius: 10px;
  font-size: 16px;
  cursor: pointer;
}
.combo li:hover { background: var(--surface); }
.combo__on, .combo__on:hover { background: var(--navy); color: var(--on-navy); }
.combo__hint { margin-left: auto; font-size: 15px; color: #45526a; white-space: nowrap; }
.combo__on .combo__hint { color: var(--on-navy-dim); }

.dlg__err {
  margin: 0;
  padding: 11px 14px;
  border-radius: 12px;
  background: #f8e0db;
  color: #6b1d0d;
  font-size: 16px;
}
.dlg__foot { display: flex; flex-wrap: wrap; gap: 10px; }

/* Края прокрутки окна. Форма в окне длиннее окна, и поле, разрезанное
   пополам прямо над кнопками, читается как налезающее на них — сломанная
   вёрстка, а не «дальше есть ещё». Поэтому край растворяем: полоса заливки
   от кнопок вверх и от заголовка вниз. Срез перестаёт быть срезом, видно,
   что содержимое уходит за край и его можно докрутить.
   Полосы рисуют сами заголовок и строка кнопок — они позиционированы, и их
   псевдоэлемент ложится поверх текста тела. Пока крутить нечего, полос нет:
   лишние перегородки в короткой форме только дробят её. */
/* Низкое окно браузера: панель вкладок, адресная строка и закладки съедают
   половину экрана ноутбука, и на форму остаётся триста точек. Отдаём ей поля
   окна: заголовок мельче, отступы у́же, зазоры плотнее — это сорок точек, ещё
   одна строка формы, которую не придётся докручивать. */
@media (max-height: 680px) {
  dialog.dlg { max-height: calc(100dvh - 16px); }
  .dlg__form { padding: 16px 20px calc(14px + env(safe-area-inset-bottom)); gap: 12px; max-height: calc(100dvh - 16px); }
  .dlg__head h3 { font-size: 21px; }
  .dlg__grid { gap: 10px 14px; }
}

.dlg__head, .dlg__foot { position: relative; }
.dlg--above .dlg__head::after, .dlg--below .dlg__foot::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  height: 34px;
  pointer-events: none;
}
.dlg--above .dlg__head::after {
  top: 100%;
  background: linear-gradient(to bottom, var(--card) 30%, rgba(255, 255, 255, 0));
}
.dlg--below .dlg__foot::before {
  bottom: 100%;
  background: linear-gradient(to top, var(--card) 30%, rgba(255, 255, 255, 0));
}

/* ---------- подтверждение действия ---------- */

.toast {
  position: fixed;
  left: 50%;
  bottom: calc(22px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  max-width: calc(100vw - 32px);
  padding: 13px 22px;
  border-radius: var(--r-pill);
  background: var(--navy);
  color: var(--on-navy);
  box-shadow: var(--shadow);
  font-size: 16px;
  text-align: center;
  z-index: 60;
}

@media (max-width: 860px) {
  .facts { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 680px) {
  .dlg__grid { grid-template-columns: minmax(0, 1fr); }
  .fld-wrap--wide { grid-column: auto; }
  /* На узком экране позиция складывается в две строки: название сверху,
     количество, цена и сумма — под ним. Шапка таблицы там уже не нужна. */
  .items__head { display: none; }
  /* Сетка, а не перенос: на переносе сумма зажималась в остаток строки, а
     кнопка уезжала на третий уровень. Здесь каждое поле знает своё место. */
  .items__row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 64px minmax(0, 1fr);
    grid-template-areas:
      "name name  name"
      "qty  unit  price"
      "sum  sum   del";
    gap: 8px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--line);
  }
  .items__row .fld[data-k="name"] { grid-area: name; }
  .items__row .fld[data-k="qty"] { grid-area: qty; }
  .items__row .fld[data-k="unit"] { grid-area: unit; }
  .items__row .fld[data-k="price"] { grid-area: price; }
  .items__sum { grid-area: sum; text-align: left; align-self: center; }
  .items__row .icon-btn { grid-area: del; justify-self: end; }
  /* Разбор накладной на телефоне: те же две строки на позицию. */
  .imp__head { display: none; }
  .imp__fields {
    grid-template-columns: minmax(0, 1fr) 64px minmax(0, 1fr);
    grid-template-areas:
      "product product product"
      "qty     unit    price"
      "sum     sum     del";
  }
  .imp__fields .fld[data-k="product"] { grid-area: product; }
  .imp__fields .fld[data-k="qty"] { grid-area: qty; }
  .imp__fields .fld[data-k="unit"] { grid-area: unit; }
  .imp__fields .fld[data-k="price"] { grid-area: price; }
  .imp__fields .fld[data-k="sum"] { grid-area: sum; }
  .imp__fields .icon-btn { grid-area: del; justify-self: end; }
  .subbar__end { margin-left: 0; width: 100%; }
  /* Четыре фильтра в одну строку на телефоне не помещаются: пилюля вылезает
     за край и тянет за собой горизонтальную прокрутку всей страницы. */
  /* На телефоне шесть колонок накладных не помещаются, и таблицу приходится
     возить вбок. Номер и дата срока уходят: срок читается по плашке, номер
     есть в карточке под списком. */
  .hide-s { display: none; }
  /* В тёмной панели таблица состава тоже не влезает в четыре колонки. */
  .spec td.hide-s, .spec th.hide-s { display: none; }

  /* Список накладных на телефоне — не таблица, а карточки. Четыре колонки в
     343 пикселя не становятся, и таблицу приходилось возить вбок: поставщик
     уходил за край вместе с суммой. Строка складывается в две: сверху главное
     (поставщик и сумма), снизу дата и состояние оплаты. */
  .stack-s thead { display: none; }
  .stack-s, .stack-s tbody { display: block; }
  .stack-s tbody tr {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 2px 10px;
    padding: 12px 14px;
  }
  .stack-s tbody tr + tr { border-top: 1px solid var(--line); }
  .stack-s td { display: block; padding: 0; border: none !important; }
  /* После блочной раскладки правило .hide-s проигрывает по специфичности —
     повторяем его с весом таблицы, иначе скрытые колонки возвращаются. */
  .stack-s td.hide-s, .stack-s th.hide-s { display: none; }
  .stack-s .c-sup { order: 1; flex: 1 1 58%; font-weight: 500; }
  .stack-s .c-sum { order: 2; margin-left: auto; font-weight: 600; }
  .stack-s .c-date { order: 3; flex: 1 1 58%; color: var(--muted); }
  .stack-s .c-pay { order: 4; margin-left: auto; }
  .stack-s .c-items { display: none; }
  /* Две суммы подряд без шапки таблицы неразличимы: на телефоне подписываем
     их тем, чем были колонки. */
  .stack-s td[data-label]::before {
    content: attr(data-label) ' ';
    color: var(--muted);
    font-weight: 400;
  }
  .stack-s tbody tr[aria-selected="true"] td[data-label]::before { color: var(--on-navy-dim); }

  /* Три плитки итогов в 375 пикселей не становятся: числа ломаются посреди
     суммы. Раскладываем по две. */
  .spec__totals { grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); }
  /* Выбранная строка — целиком, а не по ячейкам: в блочной раскладке
     скругление первой и последней ячейки пришлось бы на случайные углы. */
  .stack-s tbody tr[aria-selected="true"] {
    background: var(--navy);
    color: var(--on-navy);
    border-radius: 14px;
  }
  .stack-s tbody tr[aria-selected="true"] td,
  .stack-s tbody tr[aria-selected="true"]:hover td { background: none; border-radius: 0; }
  .stack-s tbody tr[aria-selected="true"] .muted,
  .stack-s tbody tr[aria-selected="true"] .c-date { color: var(--on-navy-dim); }
  /* Шапка группы поставщика: название на всю ширину, суммы под ним. */
  .stack-s tbody tr.grp { background: var(--surface); border-radius: 14px; }
  .stack-s tbody tr.grp td:first-child { flex: 1 1 100%; }
  .stack-s tbody tr.grp td:nth-child(2) { font-weight: 600; }
  .stack-s tbody tr.grp td:last-child { margin-left: auto; }

  .seg { flex-wrap: wrap; max-width: 100%; border-radius: var(--r-m); }
  /* Подразделам не хватало семи пикселей, и «Списания» уезжали на вторую
     строку. Поджатые поля кнопок возвращают их в одну. */
  .seg button { padding-left: 13px; padding-right: 13px; }
  .filters { width: 100%; }
}

/* Знак вида позиции: коробка — сырьё, кастрюля — заготовка, тарелка — блюдо.
   Не украшение: в номенклатуре заготовки лежат вперемешку с сырьём, и без
   знака «Рис наш» от «Риса п/ф» отличают по памяти. */
.kind {
  flex: 0 0 16px;
  width: 16px;
  height: 16px;
  margin-right: 9px;
  vertical-align: -3px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linejoin: round;
  stroke-linecap: round;
  color: var(--muted);
}
/* Цветом разводим только то, что путают: заготовку и сырьё. Блюда лежат
   отдельным разделом, их знак работает молча. */
.kind--заготовка { color: var(--warn); }
/* На тёмной панели оба цвета уходят в фон, поэтому там своя пара. */
.spec .kind,
.panel--navy .kind,
tbody tr[aria-selected="true"] .kind { color: var(--on-navy-dim); }
.spec .kind--заготовка,
.panel--navy .kind--заготовка,
tbody tr[aria-selected="true"] .kind--заготовка { color: #e8a65c; }

/* ---------- подсказки под звёздочкой ---------- */

/* Объяснения свёрнуты в звёздочку: прочитать их нужно один раз, а висели
   они всегда, и раздел читался как инструкция, а не как таблица. */
.hint {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  margin-left: 4px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--muted);
  font: 600 15px/1 var(--font);
  /* Звёздочка в шрифте сидит у верхней линии — опускаем её в центр кружка. */
  text-indent: 0;
  cursor: help;
  vertical-align: 2px;
  transition: background-color 0.12s, color 0.12s;
}
.hint::before { content: '*'; display: block; transform: translateY(3px); }
.hint:hover,
.hint:focus-visible { background: var(--lime); color: var(--ink); }
.panel--navy .hint,
.board .hint,
.spec .hint {
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.28);
  color: var(--on-navy-dim);
}
.panel--navy .hint:hover,
.spec .hint:hover { background: var(--lime); color: var(--ink); }

/* Жёлтая точка: позиции не хватает того, без чего её не продать и не
   посчитать. Что именно — в подсказке. */
.gap {
  display: inline-block;
  flex: 0 0 9px;
  width: 9px;
  height: 9px;
  margin-left: 7px;
  border-radius: 50%;
  background: #e8b21f;
  vertical-align: 1px;
  cursor: help;
}

/* Всплывашка одна на страницу и лежит в body: карточки и таблицы режут
   содержимое по краю, и подсказка внутри строки обрезалась бы ими. */
.pop {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 90;
  max-width: min(340px, calc(100vw - 20px));
  padding: 12px 14px;
  border-radius: 12px;
  /* Светлая, а не тёмная: подсказку чаще всего открывают с тёмной панели
     карточки, и тёмное на тёмном сливается в одно пятно. */
  background: var(--card);
  border: 1px solid var(--line);
  color: var(--ink);
  font-size: 15px;
  line-height: 21px;
  box-shadow: var(--shadow);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.12s;
}
.pop--on { opacity: 1; visibility: visible; }

/* В подсказке знак вида идёт первым символом строки: видно, что выбираешь —
   сырьё со склада или заготовку, которую ещё надо сварить. */
.combo .kind { margin-right: 0; align-self: center; }
.combo__on .kind { color: var(--on-navy-dim); }
.combo__on .kind--заготовка { color: #e8a65c; }

/* ---------- гости ---------- */

/* Четыре метрики в ряд: на узком экране перестраиваются сами, как и тройка. */
.row--4 { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }

/* Выделенная карточка сегмента: постоянные гости — то, ради чего всё
   остальное и считается. */
.card--lime {
  background: var(--lime);
  border-color: var(--lime-deep);
}
.card--lime .metric__label,
.card--lime .head__sub,
.card--lime .muted { color: #44511a; }

/* Любимые блюда гостя: читаются взглядом, а не построчно. */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}
.chip {
  padding: 6px 13px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, 0.12);
  font-size: 15px;
  line-height: 20px;
  white-space: nowrap;
}
.chip b { font-weight: 600; color: var(--lime); }

/* Кружок с инициалами гостя. Телефон в списке не нужен: гостей различают
   по имени, а номер нужен ровно в момент звонка — он в карточке. */
.ava {
  display: inline-flex;
  flex: 0 0 30px;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  margin-right: 10px;
  border-radius: 50%;
  background: var(--surface);
  color: var(--muted);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  vertical-align: -9px;
}
tbody tr[aria-selected="true"] .ava { background: rgba(255, 255, 255, 0.16); color: var(--on-navy); }

/* ---------- сотрудники и смены ---------- */

/* Кто вошёл — в шапке. За одним ноутбуком работают посменно, и «под кем я
   сейчас» — первый вопрос, когда в учёте оказывается не то, что ждали. */
.me { display: flex; align-items: center; gap: 10px; }
.me__name { font-weight: 500; }
.me__acc { font-size: 14px; }

.staff__now { display: flex; flex-direction: column; gap: 10px; }
.staff__avas { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; font-size: 14px; }
/* Кружок того, кто сейчас на смене, — салатовый: его видно, не читая список. */
.ava--on { background: var(--lime); color: var(--navy); }

.seg--week { display: flex; align-items: center; gap: 4px; }
.seg--week span { padding: 0 10px; font-weight: 500; white-space: nowrap; }
.seg--week button {
  width: 38px;
  height: 38px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--card);
  color: var(--ink);
  cursor: pointer;
  font-size: 16px;
}
.seg--week button:hover { border-color: var(--navy); }

.sched { width: 100%; border-collapse: collapse; }
.sched th {
  font-weight: 400;
  font-size: 14px;
  color: var(--muted);
  text-align: center;
  padding: 10px 6px;
  white-space: nowrap;
}
.sched th span { font-weight: 500; color: var(--ink); }
.sched th.is-today { color: var(--ink); }
.sched th.is-today span { position: relative; }
.sched th.is-today span::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -5px;
  width: 5px;
  height: 5px;
  margin-left: -2.5px;
  border-radius: 50%;
  background: var(--lime-deep);
}
.sched td { padding: 4px; border-top: 1px solid var(--line); vertical-align: middle; }
.sched__who { width: 1%; min-width: 210px; text-align: left; }

.sched__person {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 6px;
  border: 0;
  border-radius: var(--r-s);
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.sched__person:hover { background: var(--surface); }
.sched__person b { display: block; font-weight: 500; }
.sched__person i { font-style: normal; font-size: 13px; color: var(--muted); }

/* Клетка на весь столбец: попасть в смену пальцем должно быть легко, а
   пустая клетка — такая же цель, как занятая, иначе смену не поставить. */
.sched__cell {
  width: 100%;
  min-height: 46px;
  border: 0;
  border-radius: 14px;
  font: inherit;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}
.sched__cell--free {
  background: transparent;
  border: 1px dashed var(--line);
  color: transparent;
  font-size: 20px;
}
.sched__cell--free:hover { border-color: var(--navy); color: var(--muted); }
.sched__chip.is-now { outline: 3px solid var(--lime-deep); outline-offset: -3px; }

/* Цех виден цветом: смена в чужом цехе в этой строке заметна сразу. */
.dep--kitchen { background: var(--navy); color: var(--on-navy); }
.dep--hall { background: var(--lime); color: var(--navy); }
.dep--delivery { background: #b9c8e4; color: var(--navy); }
.dep--office { background: var(--surface); color: var(--ink); }

.sched__legend {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  padding: 12px 16px;
  font-size: 14px;
  border-top: 1px solid var(--line);
}
.sched__legend span:not(.muted) { padding: 3px 12px; border-radius: var(--r-pill); font-size: 13px; }

.staff__pass { display: flex; flex-direction: column; gap: 8px; }
.staff__pass p { display: flex; align-items: baseline; gap: 12px; margin: 0; }
.staff__pass span { min-width: 72px; font-size: 14px; }
.staff__pass b {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 22px;
  letter-spacing: 0.04em;
  user-select: all;
}

/* На узком экране неделя не влезает в семь столбцов — таблица едет вбок,
   а столбец с именем остаётся на месте: иначе непонятно, чья это строка. */
@media (max-width: 860px) {
  .sched__who { position: sticky; left: 0; background: var(--card); z-index: 1; min-width: 160px; }
  .sched td { padding: 3px; }
  .sched__cell { min-width: 64px; font-size: 14px; }
}

/* ---------- перетаскивание в номенклатуре ---------- */

/* Ручка у папки: по ней видно, что строку можно двигать. Без неё
   перетаскивание — секрет, о котором знает только тот, кто его сделал. */
.grp__grip {
  width: 12px; height: 16px;
  flex: 0 0 auto;
  cursor: grab;
  background-image: radial-gradient(circle, var(--muted) 1.1px, transparent 1.2px);
  background-size: 5px 5px;
  background-position: 0 2px;
  opacity: 0.55;
}
.grp__grip:active { cursor: grabbing; }
tr.grp:hover .grp__grip { opacity: 1; }

/* Что тащим — приглушаем, чтобы было видно, где оно сейчас. */
tr.dragging td { opacity: 0.4; }

/* Куда встанет: линия по краю строки, а не рамка вокруг. Рамка на строке
   таблицы смещает соседние ячейки на пиксель и дёргает весь список. */
tr.drop-above td { box-shadow: inset 0 2px 0 0 var(--navy); }
tr.drop-below td { box-shadow: inset 0 -2px 0 0 var(--navy); }
/* Позицию бросают в папку целиком — подсвечиваем папку, а не край. */
tr.drop-into td { background: #dce9c0; box-shadow: inset 0 0 0 2px var(--lime-deep); }

/* ---------- финансы ---------- */

/* Переключатель точек появляется со второй точки. На узком экране он уезжает
   вбок вместе со своей лентой, а не ломает строку подразделов пополам. */
.venues { max-width: 100%; overflow-x: auto; scrollbar-width: none; }
.venues::-webkit-scrollbar { height: 0; }

/* Выгрузка — ссылка, а не кнопка: файл отдаёт сервер. Выглядеть она должна
   так же, как соседние кнопки, и подчёркивания ей не нужно. */
a.btn { text-decoration: none; }

/* Отчёт о прибыли: название и сумма, под ними полоса с долей от выручки.
   Полоса здесь не украшение — по ней видно, что съедает выручку, ещё до
   того, как прочитаны проценты. */
.pnl { display: flex; flex-direction: column; gap: 15px; }
.pnl__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 3px 12px;
  align-items: baseline;
}
.pnl__name { color: var(--muted); overflow-wrap: anywhere; }
.pnl__sum { font-variant-numeric: tabular-nums; white-space: nowrap; }
.pnl__bar {
  grid-column: 1;
  align-self: center;
  height: 8px;
  border-radius: var(--r-pill);
  background: #dfe5ef;
  overflow: hidden;
}
.pnl__bar i { display: block; height: 100%; border-radius: inherit; background: var(--navy); }
.pnl__pct {
  grid-column: 2;
  text-align: right;
  font-size: 15px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* Выручка, промежуточный итог и прибыль — опоры отчёта: по ним глаз находит
   начало и конец, не читая подряд все строки между ними. */
.pnl__row--income .pnl__name,
.pnl__row--sub .pnl__name,
.pnl__row--result .pnl__name { color: var(--ink); font-weight: 500; }
.pnl__row--income .pnl__sum,
.pnl__row--sub .pnl__sum { font-size: 19px; font-weight: 600; }
.pnl__row--sub { padding-top: 13px; border-top: 1px solid var(--line); }
.pnl__row--sub .pnl__bar i { background: var(--lime-deep); }
.pnl__row--result { padding-top: 15px; border-top: 2px solid var(--navy); }
.pnl__row--result .pnl__sum { font-size: 27px; font-weight: 600; letter-spacing: -0.02em; }
.pnl__row--result .pnl__bar i { background: var(--lime-deep); }
/* Убыток не должен выглядеть как прибыль: цифра со знаком минус читается
   бегло, цвет — мгновенно. */
.pnl__row--loss .pnl__sum { color: var(--warn); }
.pnl__row--loss .pnl__bar i { background: var(--warn); }

/* Отчёт и год рядом, как в референсе: слева строки прибыли, справа
   столбики по месяцам. Разведённые по этажам, они заставляли прокручивать
   страницу, чтобы сверить «сколько вышло» с «как шло весь год». */
.fin { display: flex; flex-direction: column; gap: 16px; }
/* Панель года не растягивается под высоту отчёта: строк в отчёте
   одиннадцать, и растянутая панель превращалась в тёмное поле с парой
   столбиков наверху. Она ровно такая, сколько ей нужно. */
.fin__top { display: flex; flex-wrap: wrap; gap: 16px; align-items: flex-start; }
.fin__pnl { flex: 1 1 430px; min-width: 0; }
/* Правый столбец: год столбиками и выгрузки под ним. Без выгрузок рядом с
   длинным отчётом оставалось пустое поле в половину экрана. */
.fin__side { flex: 1.25 1 460px; min-width: 0; display: flex; flex-direction: column; gap: 16px; }
.fin__year { flex-direction: column; gap: 18px; }
.fin__year .mbars { height: 240px; }
.fin__year-foot { margin: 0; font-size: 15px; color: var(--on-navy-dim); }
.fin__year-foot b { color: var(--on-navy); font-weight: 600; }

/* Три числа над строками отчёта: по ним отвечают на вопрос «сколько вышло»,
   не читая весь путь денег. */
.fin__kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 18px;
  margin-bottom: 24px;
  padding-bottom: 22px;
  border-bottom: 1px solid var(--line);
}
.fin__kpis .kpi__num { font-size: 30px; }

/* Карточки выгрузок: что выгружаем и кнопка рядом. */
.row--4 { grid-template-columns: repeat(auto-fit, minmax(235px, 1fr)); }
.export { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; }
.export__what b { display: block; font-weight: 600; }
.export__what span { font-size: 15px; }

/* Ставки: число крупно, подпись мелко — их читают, а не вчитываются. */
.rates { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 18px; }
.rates__val {
  display: block;
  font-size: 26px;
  font-weight: 500;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.rates__name { font-size: 15px; color: var(--muted); }

/* Год столбиками: выручка и прибыль рядом по месяцам. Убыточный месяц
   остаётся без салатового столбика и помечен цветом — рисовать его вниз
   значило бы ломать шкалу ради одного месяца. */
.mbars { display: flex; align-items: stretch; gap: 8px; height: 200px; }
.mbar {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 7px;
  min-width: 0;
}
/* Пара столбиков не растягивается на всю ширину слота: в первый месяц
   работы их два на панель, и во всю ширину они читались бы как заливка. */
.mbar__pair {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 100%;
  width: 100%;
  max-width: 86px;
  margin: 0 auto;
}
.mbar__pair i { flex: 1 1 0; min-height: 3px; border-radius: 8px 8px 0 0; }
.mbar__rev { background: rgba(255, 255, 255, 0.22); }
.mbar__pro { background: var(--lime); }
.mbar__pro--loss { background: #e0796a; }
.mbar__name { font-size: 15px; text-align: center; color: var(--on-navy-dim); }
.mbars__legend { display: flex; flex-wrap: wrap; gap: 18px; font-size: 15px; color: var(--on-navy-dim); }
.mbars__key::before {
  content: "";
  display: inline-block;
  width: 10px; height: 10px;
  margin-right: 7px;
  border-radius: 3px;
}
.mbars__key--rev::before { background: rgba(255, 255, 255, 0.22); }
.mbars__key--pro::before { background: var(--lime); }

/* Расходы по видам: что из постоянных весит больше всего. */
.cats__row {
  display: grid;
  grid-template-columns: minmax(110px, 1fr) minmax(0, 2fr) auto;
  gap: 14px;
  align-items: center;
}
.cats__row + .cats__row { margin-top: 11px; }
.cats__bar { height: 10px; border-radius: var(--r-pill); background: var(--surface); overflow: hidden; }
.cats__bar i { display: block; height: 100%; border-radius: inherit; background: var(--navy); }
.cats__sum { font-variant-numeric: tabular-nums; white-space: nowrap; font-weight: 500; }

/* Закрытая статья и закрытая точка остаются в списке приглушёнными: их не
   удаляют, потому что в прошлых месяцах они были. */
tbody tr.is-off td { color: var(--muted); }

@media (max-width: 680px) {
  .cats__row { grid-template-columns: minmax(0, 1fr) auto; }
  .cats__bar { grid-column: 1 / -1; }
  .mbars { height: 160px; }
  .mbar__name { font-size: 13px; }
}

/* ---------- шапка, когда разделов стало много ---------- */

/* Восемь вкладок, марка и имя вошедшего в одну строку перестают помещаться
   около 1280 px: лента вкладок начинает переносить последнюю вкладку внутрь
   себя, а имя — ломаться пополам. Выглядит это как сбой, хотя всё на месте.
   Ниже этой ширины лента уходит на свою строку целиком и прокручивается
   вбок — так разделы можно добавлять и дальше, ничего не ломая. */
.me__name { white-space: nowrap; }
.topbar__end { flex: none; }
.tabs { flex-wrap: nowrap; }

@media (max-width: 1280px) {
  .topbar { flex-wrap: wrap; row-gap: 12px; }
  .tabs {
    order: 3;
    width: 100%;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    /* Полоса прокрутки под вкладками съедала бы их высоту и дёргала строку. */
    scrollbar-width: none;
  }
  .tabs::-webkit-scrollbar { height: 0; }
}

/* Лента едет вбок молча: на телефоне в неё помещаются четыре раздела из
   восьми, и ничто не говорит, что за краем есть ещё. Притушиваем тот край,
   за которым спрятаны вкладки, — и только пока они там есть. */
.tabs--back { mask-image: linear-gradient(to right, transparent, #000 36px); }
.tabs--more { mask-image: linear-gradient(to right, #000 calc(100% - 36px), transparent); }
.tabs--back.tabs--more {
  mask-image: linear-gradient(to right, transparent, #000 36px,
                              #000 calc(100% - 36px), transparent);
}

/* Стоп-лист кухни в разделе «Меню». Снимает позиции повар со своего экрана,
   а пропадают они с сайта — значит хозяин должен видеть это первой строкой,
   а не выяснять, куда делись двадцать блюд. */
.stopbar { display: flex; flex-direction: column; gap: 10px; }
.stopbar__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.stopbar__head b { font-size: 16px; }
.stopbar__list { display: flex; flex-wrap: wrap; gap: 8px; }
.stopbar__one {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  border-radius: 12px;
  background: #f7e4d6;
  color: #5f2d07;
}
.stopbar__one b { font-weight: 600; }
.stopbar__one i { font-style: normal; font-size: 13px; opacity: 0.75; }

/* ---------- сверка с агрегатором ---------- */

/* Три числа, ради которых открывают раздел: начислено, пришло, удержано.
   Таблицей по месяцам их не видно — там они размазаны по строкам, а решение
   принимают по итогу за всё время. */
.fin__totals {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  padding: 16px 20px;
}
.fin__totals > div {
  flex: 1 1 200px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.fin__totals b {
  font-size: 1.5rem;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}
.c-warn { color: var(--warn); }
.pad { padding: 0 20px 16px; }

/* Две стопки документов. Поле файла само по себе выглядит как «выберите
   файл» без подсказки, что именно нести, — поэтому подпись и пояснение
   внутри ярлыка, а не рядом. */
.fin__drops {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  padding: 0 20px 20px;
}
.fin__drops .drop {
  flex: 1 1 280px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 16px;
  border: 1px dashed var(--line);
  border-radius: 12px;
  cursor: pointer;
}
.fin__drops .drop:hover { border-color: var(--ink); }
.fin__drops .drop input { align-self: flex-start; }
.fin__drops .drop input:disabled { opacity: 0.5; }
