/* ============================================================================
   crew.toggle.coffee — внутренний сайт кофейни
   Тёмный монохром и Mont — как на menu.toggle.coffee, тот же дом.

   Раскладка (не «упрощать»): это оболочка приложения. Документ не скроллится,
   скроллится только <main> внутри флекс-колонки. На планшете за баром
   (WKWebView) sticky-шапки уползают при инерционном скролле, а статичная
   строка флекса уехать не может.

   Рельс с разделами: на узком — горизонтальная лента вверху, на широком
   (от 48rem) — боковое меню слева.
   ========================================================================= */

@font-face { font-family: "Mont"; src: url("/assets/fonts/Mont-Regular.woff") format("woff");  font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Mont"; src: url("/assets/fonts/Mont-SemiBold.woff") format("woff"); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: "Mont"; src: url("/assets/fonts/Mont-Bold.woff") format("woff");     font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: "Mont"; src: url("/assets/fonts/Mont-Black.woff2") format("woff2"),
                                       url("/assets/fonts/Mont-Black.woff") format("woff");    font-weight: 800; font-style: normal; font-display: swap; }

:root {
  --bg:         #050505;
  --surface:    #131313;
  --surface-2:  #1b1b1b;
  --surface-3:  #252525;

  --ink:        #f4efe6;
  --ink-2:      #a49f97;
  --ink-3:      #6a6560;

  --line:       #232323;
  --line-2:     #343434;

  --accent:     #f4efe6;
  --danger:     #e2685c;
  --warn:       #d9a441;
  --ok:         #7bbd97;

  --rail-w:     16.5rem;
  --content-w:  58rem;
  --radius:     .75rem;
  --radius-lg:  1.125rem;

  --pad-x:      clamp(1rem, 3.5vw, 2.25rem);

  color-scheme: dark;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
[hidden] { display: none !important; }

html { height: 100%; -webkit-text-size-adjust: 100%; }

body {
  min-height: 100%;
  background: var(--bg);
  color: var(--ink);
  font-family: "Mont", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
table { border-collapse: collapse; width: 100%; }

::selection { background: var(--ink); color: var(--bg); }
:focus-visible { outline: 2px solid var(--ink-2); outline-offset: 3px; border-radius: 4px; }

.skip-link { position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--ink); color: var(--bg); padding: .625rem 1rem; font-weight: 600; }
.skip-link:focus { left: 0; }

/* полосы прокрутки прячем: сайт живёт на планшете за баром */
.cats, .scroll-y { scrollbar-width: none; -ms-overflow-style: none; }
.cats::-webkit-scrollbar, .scroll-y::-webkit-scrollbar { width: 0; height: 0; display: none; }


/* ============================================================================
   ОБОЛОЧКА
   ========================================================================= */

/* Высота оболочки — ВИДИМАЯ часть окна, а не вся страница.
   На iPad клавиатура не сжимает окно: она наезжает на него и прокручивает
   страницу вверх. Оболочка ростом в 100% такого окна уезжает вместе с ней, и
   после закрытия клавиатуры снизу остаётся чёрный кусок в пол-экрана.
   `--vvh` держит в себе высоту visualViewport (её ставит crew.js), 100dvh —
   запасной вариант для браузеров без него, 100% — для совсем старых. */
body.app { height: 100%; height: 100dvh; height: var(--vvh, 100dvh); overflow: hidden; }

.shell { height: 100%; display: flex; flex-direction: column; }

.rail {
  flex: 0 0 auto;
  display: flex; flex-direction: column;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  padding-top: env(safe-area-inset-top);
}
.rail > .brandbar { border-bottom: 1px solid var(--line); }

.brandbar {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 1rem;
  min-height: 3.75rem;
  padding: .75rem var(--pad-x);
}
.brand { display: flex; align-items: center; gap: .6875rem; min-width: 0; }
.brand__logo { width: 2.5rem; height: 2.5rem; flex: 0 0 auto; border-radius: 50%; }
.brand__name b {
  font-weight: 800; font-size: 1.0625rem; letter-spacing: -.02em; line-height: 1.1;
  white-space: nowrap;
}

.brandbar__right { flex: 0 0 auto; margin-left: auto; display: flex; align-items: center; gap: .375rem; }

/* Узкий экран: «кто вошёл» — в шапке, подвал рельса не нужен вовсе. */
.railfoot { display: none; }

.who {
  display: inline-flex; align-items: center; gap: .5rem;
  min-height: 2.25rem; padding: 0 .75rem;
  border: 1px solid var(--line-2); border-radius: 999px;
  color: var(--ink-2); font-size: .75rem; font-weight: 700;
  white-space: nowrap;
  transition: color .15s, border-color .15s;
}
.who:hover { color: var(--ink); border-color: var(--ink-3); }
.who b { color: var(--ink); font-weight: 700; }
/* «Выйти» рядом с именем — и вверху на телефоне, и внизу рельса. */
.who-out {
  display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
  width: 2.25rem; height: 2.25rem;
  border: 1px solid var(--line-2); border-radius: 999px;
  color: var(--ink-3); transition: color .15s, border-color .15s;
}
.who-out:hover { color: var(--ink); border-color: var(--ink-3); }

/* ---------- лента разделов ---------- */

.cats {
  --cats-fade: 1.75rem;
  display: flex; gap: .5rem;
  overflow-x: auto; overflow-y: hidden;
  padding: .875rem var(--pad-x);
  scroll-padding-inline: var(--pad-x);
  -webkit-overflow-scrolling: touch;
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 var(--cats-fade),
                      #000 calc(100% - var(--cats-fade)), transparent 100%);
          mask-image: linear-gradient(to right, transparent 0, #000 var(--cats-fade),
                      #000 calc(100% - var(--cats-fade)), transparent 100%);
}
.cats.at-start { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - var(--cats-fade)), transparent 100%);
                         mask-image: linear-gradient(to right, #000 calc(100% - var(--cats-fade)), transparent 100%); }
.cats.at-end   { -webkit-mask-image: linear-gradient(to right, transparent 0, #000 var(--cats-fade));
                         mask-image: linear-gradient(to right, transparent 0, #000 var(--cats-fade)); }
.cats.at-start.at-end { -webkit-mask-image: none; mask-image: none; }

.cats a {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: .5rem;
  white-space: nowrap;
  min-height: 2.5rem; padding: 0 1rem;
  border-radius: 999px; border: 1px solid var(--line);
  background: var(--surface); color: var(--ink-2);
  font-size: .875rem; font-weight: 600;
  transition: background .18s, color .18s, border-color .18s, transform .12s;
}
.cats a:hover { color: var(--ink); background: var(--surface-2); border-color: var(--line-2); }
.cats a:active { transform: scale(.96); }
.cats a.active { background: var(--accent); border-color: var(--accent); color: var(--bg); font-weight: 700; }
/* счётчик-«хвостик»: сколько дел висит в разделе */
.cats .n {
  display: inline-block; min-width: 1.25rem; padding: 0 .375rem;
  border-radius: 999px; background: var(--danger); color: #120a09;
  font-size: .6875rem; font-weight: 800; text-align: center;
}
.cats a.active .n { background: var(--bg); color: var(--accent); }

/* ---------- содержимое ---------- */

.pane { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.pane > main {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  scrollbar-width: none; -ms-overflow-style: none;
}
.pane > main::-webkit-scrollbar { width: 0; height: 0; display: none; }

.wrap {
  width: 100%; max-width: var(--content-w); margin: 0 auto;
  padding: clamp(1.25rem, 3.5vw, 2.25rem) var(--pad-x) 4rem;
}
.wrap--narrow { max-width: 44rem; }


/* ============================================================================
   ТИПОГРАФИКА И БЛОКИ
   ========================================================================= */

.page-head { margin-bottom: 1.5rem; }
.page-head h1 {
  font-weight: 800; font-size: clamp(1.625rem, 4.5vw, 2.25rem);
  line-height: 1.05; letter-spacing: -.03em;
}
/* Подпись под заголовком — во всю ширину и мельче (29.09.2026, просьба
   владельца). Была колонка в 52ch: на широком экране она обрывалась на
   середине строки и текст сыпался на три строки там, где хватало одной.
   `nowrap` тут нельзя — на телефоне он вылез бы за экран боковым скроллом. */
.page-head p { margin-top: .5rem; color: var(--ink-2); font-size: .8125rem; line-height: 1.45; max-width: none; }

.eyebrow {
  display: block; margin-bottom: .375rem;
  color: var(--ink-3); font-size: .625rem; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
}

.sect { margin-top: 2.25rem; }
.sect__head { display: flex; align-items: baseline; gap: .75rem; margin-bottom: .875rem; }
.sect__head h2 { font-size: 1.125rem; font-weight: 800; letter-spacing: -.02em; }
.sect__head a { margin-left: auto; color: var(--ink-3); font-size: .8125rem; font-weight: 600; }
.sect__head a:hover { color: var(--ink); }

.card {
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface); padding: 1rem 1.125rem;
}
.card + .card { margin-top: .625rem; }
.card--flat { background: none; }

.muted { color: var(--ink-2); }
.faint { color: var(--ink-3); }
.tnum  { font-variant-numeric: tabular-nums; }
.right { text-align: right; }
.nowrap { white-space: nowrap; }

.empty {
  padding: 2.5rem 1rem; text-align: center;
  color: var(--ink-3); font-size: .9375rem;
  border: 1px dashed var(--line-2); border-radius: var(--radius);
}

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

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  min-height: 2.75rem; padding: 0 1.125rem;
  border-radius: 999px; border: 1px solid var(--line-2);
  background: var(--surface-2); color: var(--ink);
  font-size: .875rem; font-weight: 700; white-space: nowrap;
  transition: background .15s, border-color .15s, transform .12s, opacity .15s;
}
.btn:hover { background: var(--surface-3); border-color: var(--ink-3); }
.btn:active { transform: scale(.97); }
.btn[disabled] { opacity: .45; pointer-events: none; }
.btn--primary { background: var(--accent); border-color: var(--accent); color: var(--bg); }
.btn--primary:hover { background: #fff; border-color: #fff; }
.btn--ghost { background: none; }
.btn--danger { color: var(--danger); border-color: rgba(226,104,92,.35); }
.btn--danger:hover { background: rgba(226,104,92,.1); border-color: var(--danger); }
.btn--sm { min-height: 2.125rem; padding: 0 .75rem; font-size: .8125rem; }
.btn--block { width: 100%; }

.btnrow { display: flex; flex-wrap: wrap; gap: .5rem; }

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

.tag {
  display: inline-flex; align-items: center; gap: .3125rem;
  padding: .1875rem .5rem;
  border: 1px solid var(--line-2); border-radius: 999px;
  color: var(--ink-2); font-size: .6875rem; font-weight: 700;
  letter-spacing: .02em; white-space: nowrap;
}
.tag--ok    { color: var(--ok);     border-color: rgba(123,189,151,.35); }
.tag--warn  { color: var(--warn);   border-color: rgba(217,164,65,.35); }
.tag--alarm { color: var(--danger); border-color: rgba(226,104,92,.4); }
.tag--solid { background: var(--accent); border-color: var(--accent); color: var(--bg); }

/* ---------- сообщения ---------- */

.flash { margin-bottom: 1.25rem; display: flex; flex-direction: column; gap: .5rem; }
.flash__i {
  padding: .75rem 1rem; border-radius: var(--radius);
  border: 1px solid var(--line-2); background: var(--surface);
  font-size: .875rem; font-weight: 600;
}
.flash__i--ok   { border-color: rgba(123,189,151,.4); color: var(--ok); }
.flash__i--err  { border-color: rgba(226,104,92,.45); color: var(--danger); }

/* ---------- формы ---------- */

.field { display: flex; flex-direction: column; gap: .375rem; margin-bottom: 1rem; }
.field > span { color: var(--ink-2); font-size: .8125rem; font-weight: 600; }
.field > small { color: var(--ink-3); font-size: .75rem; }
.field input, .field select, .field textarea {
  width: 100%; padding: .75rem .875rem;
  border: 1px solid var(--line-2); border-radius: var(--radius);
  background: var(--surface-2); color: var(--ink);
  font: inherit; font-size: 1rem;
}
.field textarea { min-height: 9rem; resize: vertical; line-height: 1.6; }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-color: var(--ink-3); }
.field--check { flex-direction: row; align-items: center; gap: .625rem; }
.field--check input { width: 1.125rem; height: 1.125rem; }
.field--check span { color: var(--ink); font-size: .9375rem; }

.grid2 { display: grid; gap: 0 1rem; grid-template-columns: 1fr; }
@media (min-width: 34rem) { .grid2 { grid-template-columns: 1fr 1fr; } }

/* ---------- таблицы ---------- */

.tablewrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); }
.tbl { font-size: .875rem; }
.tbl th, .tbl td { padding: .625rem .75rem; text-align: left; border-bottom: 1px solid var(--line); }
.tbl th {
  color: var(--ink-3); font-size: .6875rem; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; white-space: nowrap;
}
.tbl tr:last-child td { border-bottom: 0; }
.tbl tbody tr:hover { background: var(--surface); }
/* Числовая колонка правится ЦЕЛИКОМ, вместе с заголовком. Пока правило
   висело только на `td`, шапка «Начислено» стояла слева, а суммы — справа,
   и колонка выглядела съехавшей. */
.tbl th.num, .tbl td.num { text-align: right; white-space: nowrap; }
.tbl td.num { font-variant-numeric: tabular-nums; }
/* Колонка по центру — под поля ввода (помол): число там короткое, и прижатое
   к краю оно выглядит случайным. */
.tbl th.mid, .tbl td.mid { text-align: center; white-space: nowrap; }

/* Таблица в колонке лота: те же правила, только теснее — их в строке две. */
.tbl--compact { font-size: .8125rem; }
.tbl--compact th, .tbl--compact td { padding: .4375rem .5625rem; }
.tbl--compact th { font-size: .625rem; letter-spacing: .05em; }
.tbl--compact td { font-variant-numeric: tabular-nums; }
.tbl--compact td:first-child { color: var(--ink-2); }
/* Название кофемолки переносится по словам: «Fiorenzato F4 E nano» в одну
   строку растягивает таблицу шире колонки, и её приходится листать вбок. */
.tbl--compact th:first-child, .tbl--compact td:first-child { white-space: normal; min-width: 5.5rem; }

/* Помол в карточке лота — две таблицы по два способа, ОДНА НАД ДРУГОЙ на любом
   экране. Одной таблицей на четыре способа на телефоне не помещалось и уезжало
   вбок. Рядом их тоже ставили — и там в половину ширины не влезал столбец с
   названием кофемолки, возвращая ту же прокрутку, только в двух местах. */
.grindsplit { display: grid; gap: .75rem; }

/* Помол в карточке лота: поля одной ширины, число по центру. Ширина в ch,
   а не в rem: в ячейку кладут «1,75» и «23» — четырёх знаков хватает всегда. */
.tbl--grind td { padding: .375rem .5rem; }
.grind__in {
  width: 5ch; padding: .375rem .25rem;
  border: 1px solid var(--line-2); border-radius: .5rem;
  background: var(--surface-2); color: var(--ink);
  font: inherit; font-size: .875rem; font-weight: 700;
  font-variant-numeric: tabular-nums; text-align: center;
}
.grind__in::placeholder { color: var(--ink-3); font-weight: 400; }
/* В списке лотов поле уже: там таблица вдвое теснее, чем в карточке. */
.tbl--compact .grind__in { width: 4.25ch; padding: .25rem .1875rem; font-size: .8125rem; }
/* Сохранение одной клетки: пока идёт — тусклое, легло — зелёная рамка на миг,
   не легло — красная и значение откатывается (то же, что в «Себесе»). */
.grind__in.is-saving { opacity: .55; }
.grind__in.is-saved  { border-color: var(--ok); transition: border-color .4s; }
.grind__in.is-failed { border-color: var(--danger); color: var(--danger); }

/* Значки способов приготовления (Beans::ICONS). В шапке узкой таблицы они
   стоят вместо слов — четыре слова туда не помещаются, — поэтому рядом со
   списком всегда печатается легенда `.mlegend`, а в разметке у каждого значка
   есть подпись словами (`.sr-only` или соседний текст). */
.mi { width: 1.125rem; height: 1.125rem; display: block; margin: 0 auto; }
.tbl th .mi { color: var(--ink-2); }
.mhead { display: inline-flex; flex-direction: column; align-items: center; gap: .1875rem; }
.mlegend {
  margin-top: .625rem;
  display: flex; flex-wrap: wrap; align-items: center; gap: .375rem 1rem;
  font-size: .8125rem;
}
.mlegend__i { display: inline-flex; align-items: center; gap: .375rem; color: var(--ink-2); }
.mlegend__i .mi { color: var(--ink-3); }


/* ============================================================================
   ВХОД
   ========================================================================= */

body.login-page { display: grid; place-items: center; min-height: 100dvh; padding: 1.5rem; }
.login {
  width: 100%; max-width: 24rem;
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--surface); padding: 1.75rem;
}
.login__brand { display: flex; flex-direction: column; align-items: center; gap: .75rem; margin-bottom: 1.5rem; }
.login__brand img { width: 3.5rem; height: 3.5rem; border-radius: 50%; }
.login__brand b { font-size: 1.125rem; font-weight: 800; letter-spacing: -.02em; }
.login__brand small { color: var(--ink-3); font-size: .75rem; text-align: center; }
.login .btn { margin-top: .25rem; }
.login__note { margin-top: 1.25rem; color: var(--ink-3); font-size: .75rem; text-align: center; line-height: 1.5; }

/* Кнопка Яндекса. Фирменный красный берём только на саму метку «Я»: заливать
   им всю кнопку на почти чёрном фоне — значит поставить в макет пятно, которое
   спорит с логотипом кофейни. Узнаваемости хватает и метки. */
.btn--ya { gap: .625rem; }
.btn--ya__mark {
  display: inline-grid; place-items: center;
  width: 1.375rem; height: 1.375rem; flex: 0 0 auto;
  border-radius: .3125rem;
  background: #fc3f1d; color: #fff;
  font-size: .875rem; font-weight: 800; line-height: 1;
}

/* Разделитель «или паролем» — тонкая линия по бокам от подписи. */
/* Вход по пин-коду на планшете: точки и крупная клавиатура под палец. */
.pin-dots { display: flex; justify-content: center; gap: 1rem; margin: .25rem 0 1.25rem; }
.pin-dots i {
  width: .875rem; height: .875rem; border-radius: 50%;
  border: 2px solid var(--ink-3); background: transparent; transition: background .1s;
}
.pin-dots i.is-on { background: var(--ink); border-color: var(--ink); }
.pin-pad { display: grid; grid-template-columns: repeat(3, 1fr); gap: .625rem; max-width: 17rem; margin: 0 auto; }
.pin-key {
  height: 4rem; border-radius: 1rem;
  border: 1px solid var(--line-2); background: var(--surface-2); color: var(--ink);
  font: inherit; font-size: 1.5rem; font-weight: 700; cursor: pointer;
  transition: background .1s, transform .05s;
}
.pin-key:active { background: var(--surface-3); transform: scale(.97); }
.pin-key--soft { color: var(--ink-3); font-size: 1.125rem; }
.is-busy .pin-key { opacity: .5; pointer-events: none; }
.login__or {
  display: flex; align-items: center; gap: .75rem;
  margin: 1.25rem 0;
  color: var(--ink-3); font-size: .6875rem; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
}
.login__or::before, .login__or::after {
  content: ""; flex: 1 1 auto; height: 1px; background: var(--line-2);
}

/* Ссылка-приглашение: её копируют целиком, поэтому поле, а не текст —
   по нажатию выделяется вся строка, и длинный токен не приходится ловить мышью. */
.invite-link {
  width: 100%; margin-top: .5rem; padding: .625rem .75rem;
  border: 1px solid var(--line-2); border-radius: var(--radius);
  background: var(--surface-2); color: var(--ink);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .8125rem;
}


/* ============================================================================
   СЕГОДНЯ (главная)
   ========================================================================= */

.today { display: grid; gap: .75rem; }
@media (min-width: 46rem) { .today { grid-template-columns: 1fr 1fr; } }

.tile {
  display: block;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface); padding: 1.125rem 1.25rem;
  transition: border-color .15s, background .15s;
}
a.tile:hover { border-color: var(--line-2); background: var(--surface-2); }
.tile__label {
  display: flex; align-items: center; gap: .5rem; margin-bottom: .625rem;
  color: var(--ink-3); font-size: .625rem; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
}
.tile__big { font-size: 1.5rem; font-weight: 800; letter-spacing: -.025em; line-height: 1.15; }
.tile__sub { margin-top: .375rem; color: var(--ink-2); font-size: .875rem; }
.tile--alarm { border-color: rgba(226,104,92,.45); }
.tile--alarm .tile__big { color: var(--danger); }
.tile--wide { grid-column: 1 / -1; }

/* Мои ближайшие смены на дашборде: строка = день, ведёт в сетку. */
.mine { display: flex; flex-direction: column; gap: .25rem; margin-top: .25rem; }
.mine__row {
  display: grid; grid-template-columns: 6.5rem 4.5rem 1fr auto; align-items: baseline; gap: .75rem;
  padding: .5rem .75rem; margin: 0 -.75rem;
  border-radius: .625rem; color: var(--ink-2); font-size: .875rem;
  transition: background .15s;
}
.mine__row:hover { background: var(--surface-2); }
.mine__row--today { background: var(--surface-2); }
.mine__day { color: var(--ink); font-weight: 800; }
.mine__date { color: var(--ink-3); font-variant-numeric: tabular-nums; }
.mine__time { color: var(--ink); font-weight: 700; font-variant-numeric: tabular-nums; }
.mine__role { color: var(--ink-3); font-size: .75rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
@media (max-width: 30rem) {
  .mine__row { grid-template-columns: 1fr auto; row-gap: .125rem; }
  .mine__date { order: 3; }
  .mine__role { order: 4; }
}

/* «Что купить» у владельца: строка = позиция, магазинов здесь нет (02.10.2026).
   «Нет совсем» — красным словом, а не только цветом строки. */
.buy { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .375rem; }
.buy__row { display: flex; align-items: baseline; gap: .5rem; font-size: .9375rem; }
.buy__name { flex: 1 1 0; min-width: 0; color: var(--ink); font-weight: 700; }
.buy__state { flex: 0 0 auto; color: var(--ink-3); font-size: .75rem; font-weight: 700; }
.buy__row--out .buy__state { color: var(--danger); }

.duty { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .75rem; }
.duty__p {
  display: inline-flex; align-items: baseline; gap: .5rem;
  padding: .375rem .875rem;
  border: 1px solid var(--line-2); border-radius: 999px;
  font-size: .8125rem; font-weight: 600;
}
/* Имя целиком, а не первая буква: за баром смены пересекаются, и «В» — это
   и Влад, и Варя, и Вика. Кружок с инициалом тут экономил место ценой смысла. */
.duty__name { color: var(--ink); font-size: .9375rem; font-weight: 700; letter-spacing: -.01em; }
.duty__time { color: var(--ink-3); font-variant-numeric: tabular-nums; }


/* ============================================================================
   СМЕНЫ
   ========================================================================= */

.monthbar { display: flex; align-items: center; gap: .75rem; margin-bottom: 1.25rem; }
.monthbar h1 { font-size: 1.375rem; font-weight: 800; letter-spacing: -.02em; }
.monthbar .btn { min-height: 2.25rem; padding: 0 .875rem; }
.monthbar__sp { margin-left: auto; }

.days { display: flex; flex-direction: column; gap: .5rem; }

.day {
  display: grid; gap: .5rem;
  grid-template-columns: 4.5rem 1fr;
  align-items: start;
  padding: .625rem .75rem;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface);
}
.day--today { border-color: var(--ink-3); }
/* Прошедший день открытого периода ещё правится — гасим его чуть-чуть;
   закрытый период (до 6-го и 21-го) — read-only для всех, гасим сильнее. */
.day--past   { opacity: .75; }
.day--closed { opacity: .45; }
.day--weekend .day__num { color: var(--warn); }

.day__when { padding-top: .125rem; }
.day__num { font-size: 1.125rem; font-weight: 800; letter-spacing: -.02em; line-height: 1; }
.day__wd  { display: block; margin-top: .1875rem; color: var(--ink-3); font-size: .6875rem;
            font-weight: 700; text-transform: uppercase; letter-spacing: .08em; }

/* День — список блоков со своим временем. Каждый блок в одну строку:
   время, кто стоит, действие. */
/* День — колонки бок о бок. Их две, изредка три-четыре, поэтому не жёсткая
   сетка, а auto-fit: на ноутбуке колонки встают рядом, на телефоне сами
   складываются в стопку, и ничего не нужно ловить отдельным медиазапросом. */
.cols {
  display: grid; gap: .375rem;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}
.col {
  display: flex; flex-direction: column; gap: .25rem;
  padding: .4375rem .5rem .5rem;
  border: 1px solid var(--line); border-radius: .625rem;
  background: var(--surface-2);
}
.col__head { display: flex; align-items: center; gap: .375rem; }
.col__role {
  flex: 1 1 auto;
  color: var(--ink-3); font-size: .625rem; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
}
.col__add {
  align-self: flex-start;
  padding: .1875rem .5rem;
  border: 1px dashed var(--line-2); border-radius: .4375rem;
  color: var(--ink-3); font-size: .6875rem; font-weight: 700;
}
.col__add:hover { color: var(--ink); border-style: solid; border-color: var(--ink-3); }

.day__foot { display: flex; align-items: center; gap: .375rem; margin-top: .375rem; }
/* Базовая .ed-btn — квадрат под одну стрелку. Здесь у кнопки текст, и без
   auto-ширины «+ усиление» ломалось на две строки прямо внутри квадрата. */
.day__foot .ed-btn { width: auto; padding: 0 .625rem; font-size: .75rem; font-weight: 700; white-space: nowrap; }
.col__head .ed-btn { width: 1.5rem; height: 1.5rem; }

.blocks { display: flex; flex-direction: column; gap: .25rem; }

.block {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  padding: .3125rem .5rem;
  border: 1px solid var(--line); border-radius: .5rem;
  background: var(--surface-2);
  font-size: .875rem;
}
.block--taken { border-color: var(--line-2); background: var(--surface); }
.block--add { border-style: dashed; background: none; }

.block__time { display: inline-flex; align-items: center; gap: .1875rem; flex: 0 0 auto; }
/* Час выбирается списком, но показывается как обычное время — «08:00».
   Стрелку списка убираем: в строке тайминга их было бы две, и они забирали бы
   место у имени. */
.block__time select {
  width: 4.375rem; padding: .1875rem .25rem;
  border: 1px solid transparent; border-radius: .375rem;
  background: none; color: var(--ink-2);
  font: inherit; font-size: .8125rem; font-variant-numeric: tabular-nums;
  text-align: center;
  appearance: none; -webkit-appearance: none;
}
.block__time select:hover { border-color: var(--line-2); }
.block__time select:focus { outline: none; border-color: var(--ink-3); background: var(--surface-3); color: var(--ink); }
.block__dash { color: var(--ink-3); font-size: .75rem; }

/* Отклик на автосохранение: короткая зелёная рамка вместо всплывашки.
   Правок за минуту бывает десяток, и десять уведомлений подряд — это шум. */
.block.is-saving { opacity: .6; }
.block.is-saved { border-color: var(--ok); transition: border-color .4s; }
.block.is-failed { border-color: var(--danger); }
.block__time--flat {
  color: var(--ink-3); font-size: .75rem;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* Имя сжимается, кнопки — нет.
   Раньше имя занимало столько места, сколько занимало, и точку переноса строки
   определяла его длина: со словом «свободно» кнопка «встать» уезжала на другое
   место, чем с коротким именем. Теперь имя ужимается первым (при нужде — до
   многоточия), а `flex: 0 0 auto` у кнопок держит их у правого края при любой
   ширине колонки. */
.block__who {
  flex: 1 1 3rem; min-width: 0;
  font-weight: 700;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.block__who--me { color: var(--ok); }
.block__who--free { color: var(--ink-3); font-weight: 600; }
.block__act {
  flex: 0 0 auto; margin-left: auto;
  display: inline-flex; align-items: center; gap: .375rem;
}
.block .ed-btn { width: auto; padding: 0 .5rem; font-size: .75rem; font-weight: 700; }
.block--add /* Время шага — короткое поле перед текстом: «07:00 – 7:10». Это подпись
   отрезка, а не настоящие часы, поэтому обычный текст, а не выбор времени:
   в чеклистах встречается и «до 22:00», и «в 7:30». */
.ed-slot {
  flex: 0 0 auto; width: 6.5rem;
  padding: .375rem .5rem;
  border: 1px solid transparent; border-radius: .4375rem;
  background: none; color: var(--ink-3);
  font: inherit; font-size: .75rem; font-variant-numeric: tabular-nums;
}
.ed-slot:hover { border-color: var(--line-2); }
.ed-slot:focus { outline: none; border-color: var(--ink-3); background: var(--surface-2); color: var(--ink); }

.ed-pick { max-width: 9rem; }
/* На телефоне роль уходит на свою строку: вместе с временем и именем она в
   375 пикселей не помещается, и день превращался бы в кашу переносов. */
@media (max-width: 30rem) {
  .block { flex-wrap: wrap; }
}

/* Ряд блоков в настройках: два поля времени и крестик. */
.blockrow { display: flex; align-items: center; gap: .5rem; margin-bottom: .375rem; }
.blockrow input {
  width: 7rem; padding: .5rem .625rem;
  border: 1px solid var(--line-2); border-radius: var(--radius);
  background: var(--surface-2); color: var(--ink); font: inherit;
}


/* ============================================================================
   ЧЕКЛИСТЫ
   ========================================================================= */

.prog { display: flex; align-items: center; gap: .75rem; margin-bottom: 1.25rem; }
.prog__bar { flex: 1 1 auto; height: .375rem; border-radius: 999px; background: var(--surface-3); overflow: hidden; }
.prog__fill { height: 100%; background: var(--ok); transition: width .25s; }
.prog__num { color: var(--ink-2); font-size: .8125rem; font-weight: 700; font-variant-numeric: tabular-nums; }

.slotgroup { margin-top: 1.5rem; }
.slotgroup__t {
  display: inline-block; margin-bottom: .5rem; padding: .1875rem .625rem;
  border-radius: 999px; background: var(--surface-3);
  color: var(--ink-2); font-size: .75rem; font-weight: 700; font-variant-numeric: tabular-nums;
}

.check {
  display: flex; align-items: flex-start; gap: .75rem;
  width: 100%; padding: .625rem .75rem; text-align: left;
  border: 1px solid var(--line); border-radius: .625rem;
  background: var(--surface);
  font-size: .9375rem; line-height: 1.4;
  transition: background .15s, border-color .15s, opacity .15s;
}
.check + .check { margin-top: .375rem; }
.check--sub { margin-left: 1.25rem; }
.check__box {
  flex: 0 0 auto; width: 1.375rem; height: 1.375rem; margin-top: .0625rem;
  border: 1.5px solid var(--line-2); border-radius: .4375rem;
  display: grid; place-items: center;
  color: transparent; font-size: .875rem; font-weight: 800;
}
.check.is-done { opacity: .5; }
.check.is-done .check__box { background: var(--ok); border-color: var(--ok); color: var(--bg); }
.check.is-done .check__t { text-decoration: line-through; }
.check__who { margin-left: auto; flex: 0 0 auto; color: var(--ink-3); font-size: .6875rem; white-space: nowrap; }
.check:hover { border-color: var(--line-2); background: var(--surface-2); }


/* ============================================================================
   ЧЕКЛИСТ НАЛИЧИЯ
   ========================================================================= */

.stock__again { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .625rem; margin-bottom: 1rem; }
.stock__again .muted { flex: 1 1 14rem; font-size: .875rem; }
.stock__find { margin-bottom: 1rem; }
.stock__find input { padding: .625rem 1rem; font-size: .9375rem; }
.stock__group { margin-top: 1.75rem; }
.stock__group h2 {
  margin-bottom: .625rem;
  font-size: .8125rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-2);
}
.stock__row {
  display: flex; flex-wrap: wrap; align-items: center; gap: .625rem;
  padding: .5rem .75rem;
  border: 1px solid var(--line); border-radius: .625rem;
  background: var(--surface);
}
.stock__row + .stock__row { margin-top: .3125rem; }
.stock__row.gap { margin-top: .875rem; }
/* Имя с нулевой базой: длинное название переносится внутри себя, а не
   выталкивает иконки и бегунок на новую строку; поле комментария (100%)
   при этом само встаёт под строкой. */
.stock__name { flex: 1 1 0; min-width: 0; font-size: .9375rem; }
.stock__src {
  flex: 0 0 auto; color: var(--ink-3); font-size: .625rem; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
}
/* «Заказывать заранее» — секундомер вместо слов; расшифровка в шапке. */
.stock__src--pre { display: inline-flex; align-items: center; color: var(--ink-3); }
.stock__src--inline { vertical-align: -.125rem; }
.ico-watch { width: 1rem; height: 1rem; flex: 0 0 auto; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.tag .ico-watch { width: .875rem; height: .875rem; vertical-align: -.125rem; color: var(--ink-3); }
.stock__pick {
  flex: 0 0 auto; min-width: 8.5rem;
  padding: .375rem .5rem;
  border: 1px solid var(--line-2); border-radius: .5rem;
  background: var(--surface-2); color: var(--ink);
  font: inherit; font-size: .8125rem; font-weight: 700;
}
/* .stock__pick остался как общий стиль коротких полей (обжарка, партии). */

/* Бегунок коэффициента спроса (карточка лота): дорожка нейтральная — здесь
   нет «плохо/хорошо», есть просто множитель. Ползунок — как у уровня наличия,
   чтобы палец узнавал элемент. Число рядом печатает crew.js. */
.coef { display: flex; align-items: center; gap: .75rem; }
.coef__range {
  -webkit-appearance: none; appearance: none;
  flex: 1 1 auto; height: .5rem; margin: 0; padding: 0;
  border-radius: 999px; outline: none;
  background: linear-gradient(90deg, var(--surface-3) 0%, var(--ink-3) 100%);
  cursor: pointer; touch-action: pan-y;
}
.coef__range::-webkit-slider-runnable-track { height: .5rem; border-radius: 999px; background: transparent; }
.coef__range::-moz-range-track { height: .5rem; border-radius: 999px; background: transparent; }
.coef__range::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 1.5rem; height: 1.5rem; margin-top: -.5rem;
  border-radius: 50%; background: var(--surface);
  border: .25rem solid var(--ink-2);
  box-shadow: 0 1px 4px rgba(0, 0, 0, .5);
}
.coef__range::-moz-range-thumb {
  width: 1rem; height: 1rem;
  border-radius: 50%; background: var(--surface);
  border: .25rem solid var(--ink-2);
  box-shadow: 0 1px 4px rgba(0, 0, 0, .5);
}
.coef__range:focus-visible::-webkit-slider-thumb { outline: 2px solid var(--ink); outline-offset: 2px; }
.coef__val { flex: 0 0 3rem; text-align: right; font-size: 1.125rem; font-weight: 700; }

/* Бегунок уровня: дорожка — градиент от «совсем нет» к «есть», ползунок
   красится в цвет своего положения. Нетронутая строка — серый ползунок и
   пунктирная рамка, чтобы «не отмечено» не путалось с «есть». */
.lvl { display: flex; align-items: center; gap: .625rem; flex: 0 0 auto; cursor: pointer; }
.lvl__range {
  -webkit-appearance: none; appearance: none;
  width: 7.5rem; height: .5rem; margin: 0; padding: 0;
  border-radius: 999px; outline: none; background: none;
  /* Слева «совсем нет», справа «в наличии». */
  background: linear-gradient(90deg, var(--danger) 0%, var(--warn) 50%, var(--ok) 100%);
  cursor: pointer; touch-action: pan-y;
}
/* Двухпозиционный (давление): без жёлтой середины, «меньше 3» — красное. */
.lvl__range--two { background: linear-gradient(90deg, var(--danger) 0%, var(--ok) 100%); }
.lvl__range:disabled { cursor: default; opacity: .6; }
.lvl__range::-webkit-slider-runnable-track { height: .5rem; border-radius: 999px; background: transparent; }
.lvl__range::-moz-range-track { height: .5rem; border-radius: 999px; background: transparent; }
.lvl__range::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 1.5rem; height: 1.5rem; margin-top: -.5rem;
  border-radius: 50%; background: var(--surface);
  border: .25rem solid var(--ink-3);
  box-shadow: 0 1px 4px rgba(0, 0, 0, .5);
}
.lvl__range::-moz-range-thumb {
  width: 1rem; height: 1rem;
  border-radius: 50%; background: var(--surface);
  border: .25rem solid var(--ink-3);
  box-shadow: 0 1px 4px rgba(0, 0, 0, .5);
}
.lvl__range:focus-visible::-webkit-slider-thumb { outline: 2px solid var(--ink); outline-offset: 2px; }
.lvl__label { flex: 0 0 5.5rem; font-size: .75rem; font-weight: 700; color: var(--ink-3); }
.stock__row[data-level="0"] .lvl__range::-webkit-slider-thumb { border-color: var(--ok); }
.stock__row[data-level="1"] .lvl__range::-webkit-slider-thumb { border-color: var(--warn); }
.stock__row[data-level="2"] .lvl__range::-webkit-slider-thumb { border-color: var(--danger); }
.stock__row[data-level="0"] .lvl__range::-moz-range-thumb { border-color: var(--ok); }
.stock__row[data-level="1"] .lvl__range::-moz-range-thumb { border-color: var(--warn); }
.stock__row[data-level="2"] .lvl__range::-moz-range-thumb { border-color: var(--danger); }
.stock__row[data-level="0"] .lvl__label { color: var(--ok); }
.stock__row[data-level="1"] .lvl__label { color: var(--warn); }
.stock__row[data-level="2"] .lvl__label { color: var(--danger); }
/* У двухпозиционного уровень 1 — уже «меньше 3», красное (правила ниже общих — перебивают). */
.stock__row--two[data-level="1"] .lvl__range::-webkit-slider-thumb { border-color: var(--danger); }
.stock__row--two[data-level="1"] .lvl__range::-moz-range-thumb { border-color: var(--danger); }
.stock__row--two[data-level="1"] .lvl__label { color: var(--danger); }
/* Нетронутая строка — умолчание «в наличии»: выглядит как отмеченная, только
   рамка чуть тише. Подсказка «вчера: совсем нет» — чтобы умолчание не съело
   вчерашнюю тревогу. */
.stock__row[data-touched="0"] { border-color: var(--line-2); }
.stock__hint {
  display: block; margin-top: .125rem;
  color: var(--warn); font-size: .6875rem; font-weight: 700;
}
.stock__pen {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 1.75rem; height: 1.75rem; padding: 0;
  border: 1px solid var(--line-2); border-radius: .5rem;
  background: var(--surface-2); color: var(--ink-3); cursor: pointer;
}
.stock__pen:hover { color: var(--ink); }
.ico-pen { width: .875rem; height: .875rem; }
.stock__row.has-note .stock__pen { color: var(--warn); border-color: rgba(217,164,65,.45); }
.stock__note-text { display: block; margin-top: .125rem; color: var(--ink-2); font-size: .75rem; }
.stock__note-text:empty { display: none; }
.stock__note { flex: 1 1 100%; }
.stock__note input {
  width: 100%; padding: .375rem .5rem;
  border: 1px solid var(--line-2); border-radius: .5rem;
  background: var(--surface-2); color: var(--ink); font: inherit; font-size: .8125rem;
}
.stock__row.is-failed .stock__pen { color: var(--danger); }
.stock__confirm {
  margin-top: 1.75rem; padding: 1rem;
  border: 1px solid var(--line); border-radius: .75rem; background: var(--surface);
}
.stock__confirm .muted { margin: 0 0 .75rem; font-size: .8125rem; }
.stock__confirm .btn { max-width: 100%; white-space: normal; }
@media (max-width: 30rem) { .stock__confirm .btn { width: 100%; } }
@media (max-width: 30rem) {
  /* На телефоне название и бегунок в две строки: иначе имя обрезается. */
  .lvl { flex: 1 1 100%; padding-left: 0; }
  .lvl__range { flex: 1 1 auto; width: auto; }
}

/* Себестоимость: разделы-карточки, строки-сетка, всё правится на месте. */
.cs { margin-top: 1.25rem; padding: .75rem .875rem 1rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.cs--new { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; border-style: dashed; background: transparent; }
.cs--new input, .cs__add input[type="text"] {
  flex: 1 1 12rem; min-width: 0; padding: .4375rem .625rem;
  border: 1px solid var(--line-2); border-radius: .5rem;
  background: var(--surface-2); color: var(--ink); font: inherit; font-size: .8125rem;
}
.cs__head { display: flex; align-items: center; gap: .625rem; margin-bottom: .5rem; }
.cs__title {
  flex: 1 1 auto; min-width: 0; padding: .25rem .5rem; margin-left: -.5rem;
  border: 1px solid transparent; border-radius: .4375rem; background: none;
  color: var(--ink); font: inherit; font-size: 1rem; font-weight: 800; letter-spacing: -.01em;
}
.cs__title:hover { border-color: var(--line-2); }
.cs__title:focus { outline: none; border-color: var(--ink-3); background: var(--surface-2); }
.cs__count { flex: 0 0 auto; color: var(--ink-3); font-size: .75rem; font-weight: 700; }
.cs__rows { display: flex; flex-direction: column; gap: .25rem; }
.cs__add { display: flex; gap: .5rem; margin-top: .625rem; }

.crow {
  display: grid; align-items: center; gap: .25rem .5rem;
  grid-template-columns: 1.25rem minmax(10rem, 1fr) 5.5rem 6.5rem 5.5rem 3.5rem auto;
  padding: .25rem .5rem .375rem;
  border: 1px solid transparent; border-radius: .625rem;
  transition: background .15s, border-color .15s;
}
.crow:hover { background: var(--surface-2); }
.crow.is-dragging { opacity: .35; border-style: dashed; border-color: var(--line-2); }
.crow.is-saved { border-color: var(--ok); }
.crow.is-failed .crow__cost { color: var(--danger); }
.crow--ing { grid-template-columns: 1.25rem minmax(9rem, 1fr) 8rem 7rem 6rem 7rem auto; }
.crow__title, .crow__formula, .crow__key, .crow__num {
  min-width: 0; padding: .3125rem .5rem;
  border: 1px solid transparent; border-radius: .4375rem;
  background: transparent; color: var(--ink); font: inherit; font-size: .875rem;
  transition: border-color .15s, background .15s;
}
.crow__title:hover, .crow__formula:hover, .crow__key:hover, .crow__num:hover { border-color: var(--line-2); }
.crow__title:focus, .crow__formula:focus, .crow__key:focus, .crow__num:focus { outline: none; border-color: var(--ink-3); background: var(--surface-3); }
.crow__title { font-weight: 700; }
.crow__key { font-family: ui-monospace, Menlo, monospace; font-size: .75rem; color: var(--ink-2); }
.crow__num { width: 100%; text-align: right; font-variant-numeric: tabular-nums; font-weight: 700; }
.crow__price { display: inline-flex; align-items: center; gap: .25rem; }
.crow__price em { color: var(--ink-3); font-style: normal; font-size: .75rem; }
.crow__cost, .crow__margin, .crow__pct, .crow__unit { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; font-size: .875rem; }
.crow__cost { color: var(--ink-2); }
.crow__margin { font-weight: 700; }
.crow__pct { font-weight: 800; }
.crow__unit em { color: var(--ink-3); font-style: normal; font-size: .6875rem; }
.crow__pct.is-good, .pct-dot.is-good { color: var(--ok); }
.crow__pct.is-so,   .pct-dot.is-so   { color: var(--warn); }
.crow__pct.is-low,  .pct-dot.is-low  { color: var(--danger); }
.pct-dot { display: inline-block; width: .625rem; height: .625rem; border-radius: 50%; background: currentColor; vertical-align: -.0625rem; }
.crow__act { display: inline-flex; gap: .25rem; justify-content: flex-end; }
.crow__act form { display: inline; }
.crow__f { grid-column: 2 / -1; display: flex; gap: .5rem; align-items: center; }
.crow__formula { flex: 1 1 auto; font-family: ui-monospace, Menlo, monospace; font-size: .75rem; color: var(--ink-2); }
.crow__f .crow__key { flex: 0 0 8rem; }
.crow input.is-saving { opacity: .6; }
.crow input.is-saved { border-color: var(--ok); }
.crow input.is-failed, .cs__title.is-failed { border-color: var(--danger); color: var(--danger); }
[data-cost-board].is-failed .cs { border-color: var(--danger); }
@media (max-width: 48rem) {
  /* Телефон: название и кнопки, под ними числа в строку с подписями, ниже формула. */
  .crow { display: flex; flex-wrap: wrap; align-items: center; gap: .25rem .625rem; }
  .crow .ed-grip { order: 0; }
  .crow__title { order: 1; flex: 1 1 6rem; }
  .crow__act { order: 2; }
  .crow__cost, .crow__price, .crow__margin, .crow__pct, .crow__unit, .crow--ing .crow__key { order: 3; flex: 0 0 auto; text-align: left; }
  .crow__cost::before, .crow__margin::before, .crow__pct::before, .crow__unit::before {
    color: var(--ink-3); font-size: .625rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; margin-right: .25rem;
  }
  .crow__cost::before { content: 'себес'; }
  .crow__margin::before { content: 'маржа'; }
  .crow--ing .crow__unit::before { content: 'за ед.'; }
  .crow--ing .crow__unit em { display: none; }
  .crow__num { width: 4.5rem; }
  .crow--ing .crow__key { flex: 1 1 100%; }
  .crow__f { order: 4; flex: 1 1 100%; }
  .crow__f .crow__key { flex: 0 0 5rem; }
}

.legend { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1rem; }


/* ============================================================================
   РЕДАКТОР СПИСКОВ (чеклист наличия, каталог техкарт)
   Работа за ноутбуком: строки плотные, всё в одну линию, перенос — только
   когда экран действительно узкий.
   ========================================================================= */

.ed-group { margin-bottom: 1.5rem; }

.ed-ghead {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  margin-bottom: .5rem; padding-bottom: .5rem;
  border-bottom: 1px solid var(--line-2);
}
.ed-gtitle {
  flex: 1 1 12rem; min-width: 0;
  padding: .375rem .5rem;
  border: 1px solid transparent; border-radius: .5rem;
  background: none; color: var(--ink);
  font: inherit; font-size: 1rem; font-weight: 800; letter-spacing: -.015em;
}
.ed-gtitle:hover { border-color: var(--line-2); }
.ed-gtitle:focus { outline: none; border-color: var(--ink-3); background: var(--surface-2); }
.ed-count { flex: 0 0 auto; color: var(--ink-3); font-size: .75rem; }

/* Примечание ко всей категории — во всю ширину, отдельной строкой:
   это фраза, а не подпись, и в строку заголовка она не влезает. */
.ed-note {
  width: 100%; margin-bottom: .5rem;
  padding: .375rem .5rem;
  border: 1px solid transparent; border-radius: .4375rem;
  background: none; color: var(--ink-2); font: inherit; font-size: .8125rem;
}
.ed-note:hover { border-color: var(--line-2); }
.ed-note:focus { outline: none; border-color: var(--ink-3); background: var(--surface-2); color: var(--ink); }

.ed-open {
  flex: 0 0 auto;
  padding: .1875rem .5rem;
  border: 1px solid var(--line-2); border-radius: .4375rem;
  color: var(--ink-3); font-size: .6875rem; font-weight: 700; white-space: nowrap;
}
.ed-open:hover { color: var(--ink); border-color: var(--ink-3); }
.ed-open b { color: var(--warn); font-weight: 700; }

.ed-list { list-style: none; display: flex; flex-direction: column; gap: .25rem; }

.ed-row {
  display: flex; align-items: center; gap: .375rem; flex-wrap: wrap;
  padding: .3125rem .5rem;
  border: 1px solid var(--line); border-radius: .5rem;
  background: var(--surface);
}
.ed-row.is-hidden { opacity: .45; }
.ed-row.is-dragging { opacity: .35; border-style: dashed; }
.ed-row:target { border-color: var(--ok); }

.ed-grip {
  flex: 0 0 auto; width: 1.25rem;
  color: var(--ink-3); font-size: .875rem; line-height: 1;
  text-align: center; cursor: grab; user-select: none;
}
.ed-grip:active { cursor: grabbing; }
.ed-grip--demo { display: inline-block; cursor: default; }

.ed-title {
  flex: 1 1 12rem; min-width: 0;
  padding: .375rem .5rem;
  border: 1px solid transparent; border-radius: .4375rem;
  background: none; color: var(--ink); font: inherit; font-size: .9375rem;
}
.ed-title:hover { border-color: var(--line-2); }
.ed-title:focus { outline: none; border-color: var(--ink-3); background: var(--surface-2); }

/* Время шага — короткое поле перед текстом: «07:00 – 7:10». Это подпись
   отрезка, а не настоящие часы, поэтому обычный текст, а не выбор времени:
   в чеклистах встречается и «до 22:00», и «в 7:30». */
.ed-slot {
  flex: 0 0 auto; width: 6.5rem;
  padding: .375rem .5rem;
  border: 1px solid transparent; border-radius: .4375rem;
  background: none; color: var(--ink-3);
  font: inherit; font-size: .75rem; font-variant-numeric: tabular-nums;
}
.ed-slot:hover { border-color: var(--line-2); }
.ed-slot:focus { outline: none; border-color: var(--ink-3); background: var(--surface-2); color: var(--ink); }

.ed-pick {
  flex: 0 0 auto; max-width: 10rem;
  padding: .25rem .375rem;
  border: 1px solid var(--line-2); border-radius: .4375rem;
  background: var(--surface-2); color: var(--ink-2);
  font: inherit; font-size: .75rem;
}
.ed-pick:focus { outline: none; border-color: var(--ink-3); color: var(--ink); }
.ed-prio { display: inline-flex; align-items: center; gap: .25rem; color: var(--ink-3); font-size: .6875rem; font-weight: 700; }
.ed-prio input {
  width: 2.25rem; padding: .25rem .25rem; text-align: center;
  border: 1px solid var(--line-2); border-radius: .4375rem;
  background: var(--surface-2); color: var(--ink-2); font: inherit; font-size: .75rem;
}

.ed-flag {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: .25rem;
  color: var(--ink-3); font-size: .6875rem; white-space: nowrap; cursor: pointer;
}
.ed-flag input { width: .875rem; height: .875rem; }

.ed-btn {
  flex: 0 0 auto;
  width: 1.75rem; height: 1.75rem;
  display: grid; place-items: center;
  border: 1px solid var(--line-2); border-radius: .4375rem;
  color: var(--ink-2); font-size: .8125rem; line-height: 1;
  transition: color .15s, border-color .15s, background .15s;
}
.ed-btn:hover { color: var(--ink); background: var(--surface-3); }
.ed-btn[disabled] { opacity: .3; pointer-events: none; }
.ed-btn--del { width: auto; padding: 0 .5rem; color: var(--ink-3); }
.ed-btn--del:hover { color: var(--danger); border-color: var(--danger); background: rgba(226,104,92,.1); }

/* Свёрнутый список скрытых позиций: с глаз убран, но восстановим. */
.ed-hidden { margin: 1.5rem 0; }
.ed-hidden > summary {
  cursor: pointer; padding: .5rem 0;
  color: var(--ink-3); font-size: .8125rem; font-weight: 700;
}
.ed-hidden > summary:hover { color: var(--ink); }
.ed-hidden .ed-row { opacity: .55; }
.ed-hidden .ed-src { flex: 0 0 auto; color: var(--ink-3); font-size: .75rem; }

.ed-add { display: flex; gap: .5rem; margin-top: .5rem; }
.ed-add input {
  flex: 1 1 auto; min-width: 0;
  padding: .5rem .625rem;
  border: 1px dashed var(--line-2); border-radius: .5rem;
  background: none; color: var(--ink); font: inherit; font-size: .875rem;
}
.ed-add input:focus { outline: none; border-style: solid; border-color: var(--ink-3); }

/* Панель сохранения липнет к низу: список длинный, и кнопка, уехавшая на
   двести строк вниз, равносильна её отсутствию. */
.ed-bar {
  position: sticky; bottom: 0; z-index: 5;
  display: flex; align-items: center; gap: .625rem;
  margin: 1.5rem calc(var(--pad-x) * -1) 0;
  padding: .75rem var(--pad-x) calc(.75rem + env(safe-area-inset-bottom));
  border-top: 1px solid var(--line-2);
  background: var(--bg);
}
.ed-bar__note { flex: 1 1 auto; color: var(--ink-3); font-size: .75rem; }
.ed-bar.is-dirty { border-top-color: var(--warn); }
.ed-bar.is-dirty .ed-bar__note { color: var(--warn); }

/* ============================================================================
   ДОКУМЕНТЫ: регламент и техкарты
   ========================================================================= */

.doc { max-width: 42rem; }
.doc h2 { margin: 2rem 0 .75rem; font-size: 1.25rem; font-weight: 800; letter-spacing: -.02em; }
.doc h3 { margin: 1.25rem 0 .5rem; font-size: .9375rem; font-weight: 800; color: var(--ink-2); }
.doc p  { margin: .625rem 0; line-height: 1.65; }
.doc ol { margin: .75rem 0 .75rem 1.25rem; }
.doc ol li { margin: .3125rem 0; line-height: 1.6; padding-left: .25rem; }
.doc mark { background: rgba(217,164,65,.28); color: var(--ink); border-radius: .1875rem; padding: 0 .125rem; }

.clause { padding: 1rem 0; border-top: 1px solid var(--line); }
.clause:first-child { border-top: 0; }
.clause__n {
  display: inline-block; margin-bottom: .375rem;
  color: var(--ink-3); font-size: .75rem; font-weight: 800; font-variant-numeric: tabular-nums;
}
.clause__edit { float: right; color: var(--ink-3); font-size: .75rem; font-weight: 700; }
.clause__edit:hover { color: var(--ink); }

.tiles { display: grid; gap: .625rem; grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr)); }
.tiles a {
  display: flex; flex-direction: column; gap: .25rem;
  padding: 1rem 1.125rem;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface);
  transition: border-color .15s, background .15s, transform .12s;
}
.tiles a:hover { border-color: var(--line-2); background: var(--surface-2); }
.tiles a:active { transform: scale(.99); }
.tiles b { font-size: 1rem; font-weight: 800; letter-spacing: -.015em; }
.tiles small { color: var(--ink-3); font-size: .75rem; }

.cardnav { display: flex; gap: .5rem; margin-top: 2.5rem; padding-top: 1.25rem; border-top: 1px solid var(--line); }
.cardnav a { flex: 1 1 0; min-width: 0; }
.cardnav .btn { width: 100%; justify-content: flex-start; }
.cardnav .btn span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* поиск */
.searchbox { display: flex; gap: .5rem; margin-bottom: 1.5rem; }
.searchbox input {
  flex: 1 1 auto; padding: .75rem 1rem;
  border: 1px solid var(--line-2); border-radius: 999px;
  background: var(--surface-2); color: var(--ink); font: inherit; font-size: 1rem;
}
.searchbox input:focus { outline: none; border-color: var(--ink-3); }
.hit { display: block; padding: .875rem 0; border-top: 1px solid var(--line); }
.hit:first-of-type { border-top: 0; }
.hit__kind { color: var(--ink-3); font-size: .6875rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
.hit b { display: block; margin: .1875rem 0; font-size: 1rem; font-weight: 800; }
.hit p { color: var(--ink-2); font-size: .875rem; line-height: 1.5; }

/* помол */
.grind td, .grind th { text-align: center; }
.grind td:first-child, .grind th:first-child { text-align: left; }
.grind .v { font-variant-numeric: tabular-nums; font-weight: 700; }
.grind .m { color: var(--warn); font-size: .75rem; font-weight: 700; }
.grind tr:has(.m) { background: var(--surface); }

/* зерно */
.lot { border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); padding: 1rem 1.125rem; }
.lot + .lot { margin-top: .625rem; }
.lot__head { display: flex; align-items: baseline; gap: .625rem; flex-wrap: wrap; }
.lot__head b { font-size: 1.0625rem; font-weight: 800; letter-spacing: -.02em; }
.lot__grinds { margin-top: .75rem; display: grid; gap: .375rem; }
.lot__g { display: flex; align-items: baseline; gap: .625rem; font-size: .875rem; }
.lot__g > span:first-child { flex: 0 0 11rem; color: var(--ink-3); font-size: .8125rem; }
.lot__g em { font-style: normal; color: var(--ink-3); font-size: .75rem; }
.lot__g b { font-variant-numeric: tabular-nums; }
/* Кнопки действий прямо в строке лота (29.09.2026): помол, бункеры, правка,
   архив. Отбивка сверху — чтобы не слипались с ценами и помолом. */
.lot__acts { margin-top: .875rem; }

/* Цены и помол — две колонки (29.09.2026). На телефоне колонки складываются
   друг под друга: рядом они там не помещаются, а резать числа нельзя.
   Внутри колонки подпись строки уже, чем в полноширинном списке: «1 кг» и
   «200 г» коротки, а название кофемолки уходит на свою строку целиком —
   «Fiorenzato F4 E nano» в половину ширины не влезает. */
.lot__cols { margin-top: .75rem; display: grid; gap: 1rem; }
.lot__cols .lot__grinds { margin-top: 0; }
.lot__cols .lot__g { flex-wrap: wrap; row-gap: .125rem; }
.lot__coltitle {
  margin-bottom: .375rem;
  color: var(--ink-3); font-size: .6875rem; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
}
.lot__col--price .lot__g > span:first-child { flex: 0 0 3.5rem; }
.lot__col--grind .lot__g > span:first-child { flex: 0 0 100%; }
@media (min-width: 48rem) {
  /* Цены уже помола: у них три числа, у помола четыре и длинные названия
     кофемолок. Поровну делить было нечего — в ценах оставалось пустое место. */
  .lot__cols { grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); gap: 1rem 1.75rem; }
  .lot__cols--one { grid-template-columns: minmax(0, 1fr); }
}


/* ============================================================================
   ШИРОКИЙ ЭКРАН — рельс становится боковым меню
   ========================================================================= */

@media (min-width: 48rem) {
  .shell { flex-direction: row; }

  .rail {
    width: var(--rail-w); height: 100%;
    border-bottom: 0; border-right: 1px solid var(--line);
    background: var(--surface);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .rail > .brandbar { padding: .9375rem .875rem; }
  .rail > .brandbar .brand__logo { width: 2.25rem; height: 2.25rem; }

  .cats {
    flex: 1 1 auto; min-height: 0;
    flex-direction: column; gap: .125rem;
    overflow-x: hidden; overflow-y: auto;
    padding: .625rem .625rem 1rem;
    -webkit-mask-image: none; mask-image: none;
  }
  .cats a {
    justify-content: flex-start; white-space: normal;
    min-height: 0; padding: .5625rem .875rem;
    border: 0; border-radius: .625rem; background: none;
    font-size: .9375rem; line-height: 1.3;
  }
  .cats a:hover { background: var(--surface-3); }
  .cats a.active { background: var(--accent); color: var(--bg); }
  .cats .n { margin-left: auto; }

  .railfoot {
    flex: 0 0 auto; padding: .625rem;
    border-top: 1px solid var(--line);
    display: block;
  }
  .railfoot { display: flex; align-items: center; gap: .375rem; }
  .railfoot .who { flex: 1 1 auto; min-width: 0; justify-content: flex-start; border-radius: .625rem; }
  .railfoot .who b { overflow: hidden; text-overflow: ellipsis; }
  .railfoot .who-out { border-radius: .625rem; }
  .who--top { display: none; }
}

@media (min-width: 64rem) { :root { --rail-w: 17.5rem; } }

@media (max-width: 30rem) {
  /* iOS Safari принудительно приближает страницу, если у поля шрифт меньше
     16px, и обратно не отдаляет. В оболочке с overflow:hidden это оставляет
     страницу обрезанной без шанса вернуться — держим ровно 16. */
  .field input, .field select, .field textarea, .searchbox input, .stock__pick { font-size: 16px; }
  .day { grid-template-columns: 3.5rem 1fr; }
}

@media print {
  .rail, .btnrow, .btn { display: none !important; }
  body, .wrap { background: #fff; color: #000; }
  body.app { height: auto; overflow: visible; }
  .card, .stock__row, .check { border-color: #ccc; background: #fff; }
}

/* ─── «Добавить на главный экран» ────────────────────────────────────────────
   Плашка над подвалом. Из PHP приходит скрытой: показывает её только a2hs.js и
   только на телефоне, где это выполнимо (iPhone/Android, не встроенный вебвью).
   Панель с шагами раскрывается на месте — отдельная модалка тут не нужна. */
.a2hs{margin-top:3rem}
.a2hs__bar{
  display:flex;align-items:center;gap:.875rem;width:100%;
  padding:.9rem 1.05rem;font:inherit;text-align:left;cursor:pointer;color:var(--ink);
  background:var(--surface);border:1px solid var(--line-2);border-radius:var(--radius,.75rem);
}
.a2hs__bar:hover{background:var(--surface-2);border-color:var(--ink-3)}
.a2hs__ico{
  flex:0 0 auto;width:2.25rem;height:2.25rem;display:flex;align-items:center;justify-content:center;
  background:var(--surface-3);border-radius:50%;color:var(--ink-2);
}
.a2hs__ico svg{width:1.1875rem;height:1.1875rem;display:block}
.a2hs__txt{display:flex;flex-direction:column;gap:.15rem;min-width:0}
.a2hs__txt b{font-size:.9375rem;font-weight:700;letter-spacing:-.01em}
.a2hs__txt small{color:var(--ink-3);font-size:.75rem;line-height:1.35}
.a2hs__go{margin-left:auto;flex:0 0 auto;color:var(--ink-2);font-size:1.25rem;line-height:1}
.a2hs__bar[aria-expanded="true"] .a2hs__go{transform:rotate(45deg)}
.a2hs__panel{
  margin-top:.5rem;padding:1rem 1.05rem 1.25rem;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--radius,.75rem);
}
.a2hs-intro{margin:0 0 .5rem;color:var(--ink-2);font-size:.875rem;line-height:1.5}
.a2hs-steps{list-style:none;margin:0;padding:0;counter-reset:a2hs}
.a2hs-steps li{
  display:flex;align-items:flex-start;gap:.75rem;
  padding:.75rem 0;border-top:1px solid var(--line);font-size:.9375rem;line-height:1.45;
}
.a2hs-steps li::before{
  counter-increment:a2hs;content:counter(a2hs);
  flex:0 0 auto;width:1.5rem;height:1.5rem;margin-top:.0625rem;
  display:flex;align-items:center;justify-content:center;border-radius:50%;
  background:var(--surface-3);color:var(--ink-2);font-size:.75rem;font-weight:700;
}
.a2hs-ico{display:inline-flex;vertical-align:-.2em;margin:0 .125rem;width:1.125rem;height:1.125rem;color:var(--ink)}
.a2hs-ico svg{width:100%;height:100%}
.a2hs-hint{margin:.875rem 0 0;color:var(--ink-3);font-size:.8125rem;line-height:1.45}
.a2hs-act{display:flex;flex-direction:column;align-items:flex-start;gap:.625rem;margin-top:1.125rem}
.a2hs-off{
  padding:0;background:none;border:0;cursor:pointer;font:inherit;
  color:var(--ink-3);font-size:.8125rem;text-decoration:underline;
}
.a2hs-off:hover{color:var(--ink-2)}
