/* ═══════════════════════════════════════════════════════════
   Продажа товара — касса и чек
   ═══════════════════════════════════════════════════════════
   Слева пробивают, справа печатается чек. Чек здесь настоящий
   документ, а не блок формы: бумажная лента с рваными краями
   лежит на тёмном поле, и по ней сразу видно то, ради чего
   в кассе и стоят — что в корзине, сколько вышло, чем платили
   и сколько ещё должны.

   Метафора взята ровно настолько, насколько работает: рваный
   край и моноширинные цифры говорят «это чек», но бумага не
   пожелтевшая, шрифт не матричный и тени под ней настоящие —
   иначе получилась бы игра в кассу, а не инструмент.        */
.dlg.dlg-sale{
  width:min(940px,calc(100vw - 48px));max-height:min(86dvh,700px);position:fixed;
  --sl-rail:328px;
}
.sl-main{display:grid;grid-template-columns:1fr var(--sl-rail);flex:1;min-height:0}
.sl-left{
  position:relative;display:flex;flex-direction:column;min-width:0;min-height:0;
  border-right:1px solid var(--rule);
}
/* Кромка прокрутки: у обрезанной строки должно быть видно, что она
   обрезана, а не что бланк на ней кончился. */
.sl-left::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:24px;pointer-events:none;
  background:linear-gradient(to top,var(--card),rgba(255,255,255,0));
}
.sl-head{
  display:flex;align-items:center;gap:11px;padding:0 15px 0 22px;min-height:53px;
  border-bottom:1px solid var(--rule);background:var(--paper);flex-shrink:0;
}
.sl-head b{font-size:17px;font-weight:600;letter-spacing:-.035em}
.sl-head span{
  min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:11.5px;color:var(--ink-3);
}
.sl-head .sh-close{margin-left:auto}
.sl-form{padding:17px 22px 20px;overflow-y:auto;flex:1;min-height:0}

.sl-sec+.sl-sec{margin-top:18px;padding-top:17px;border-top:1px solid var(--rule-2)}
.sl-sec h3{
  display:flex;align-items:center;gap:9px;margin-bottom:11px;
  font-size:11px;font-weight:500;
  color:var(--ink-3);
}
.sl-sec h3::after{content:"";flex:1;height:1px;background:var(--rule-2)}

/* ── кому ──
   «Без брони» стоит первым и выглядит как все: это самый частый случай,
   и он не должен читаться как отказ от чего-то. */
.sl-who{display:flex;flex-wrap:wrap;gap:7px}
.sl-card{
  display:flex;align-items:center;gap:9px;padding:7px 13px 7px 8px;text-align:left;
  border:1px solid var(--rule);border-radius:var(--r-sm);background:var(--card);transition:var(--t-tap) var(--ease);transition-property:background-color,border-color,box-shadow,transform;
}
.sl-card>i{
  display:flex;align-items:center;justify-content:center;width:28px;height:28px;flex-shrink:0;
  border-radius:var(--r-sm);background:var(--sunk);color:var(--ink-2);
}
.sl-card>i.av{
  font-size:10px;font-weight:500;letter-spacing:.02em;
  background:var(--accent);color:var(--accent-ink);
}
.sl-card b{display:block;font-size:12.5px;font-weight:600;letter-spacing:-.015em;color:var(--ink)}
.sl-card u{
  display:block;margin-top:1px;font-size:10.5px;color:var(--ink-3);text-decoration:none;
}
@media (hover:hover) and (pointer:fine){
  .sl-card:hover{border-color:var(--ink-3);background:var(--sunk)}
}
.sl-card:active{transform:scale(.985)}
.sl-card.on{border-color:var(--accent);box-shadow:inset 0 0 0 1px var(--accent)}
.sl-card:focus-visible{outline:2px solid var(--ink);outline-offset:1px}

/* ── что продаём ──
   Одна строка на оба случая: набранное имя и фильтрует справочник,
   и становится своей позицией, если в справочнике такого нет. */
.sl-add{display:flex;gap:7px;margin-bottom:11px}

/* ── поле цены: появляется только под свой случай ──
   Пока позицию выбирают из справочника, цена своя, и спрашивать её не о
   чем. Поле выезжает на той букве, где справочник кончился: набранное
   имя перестало что-то находить — значит пробиваем своё (SPEC §6.1).

   Движение рассказывает именно это: строка имени **отдаёт место**, поле
   раскрывается на освободившемся, и кнопка приходит следом — а не всё
   трое возникают разом. Поэтому раскрытие идёт по основе (flex-basis)
   с торможением к концу, содержимое поля догоняет его на 90 мс позже,
   а кнопка — ещё на 30 мс. Уход вдвое короче входа: исчезновение никто
   не разглядывает.

   Класс живёт одну перерисовку: справочник фильтруется на каждой букве,
   и дёргать поле на каждой было бы враньём о том, что что-то изменилось. */
.sl-add:not(.ask) .sl-add-price,
.sl-add:not(.ask) .sl-add-go{display:none}

.sl-add.in .sl-add-price{animation:slAskOpen .3s var(--ease) backwards;overflow:hidden}
.sl-add.in .sl-add-price>*{animation:slAskInk .22s var(--ease) .09s backwards}
.sl-add.in .sl-add-go{animation:slAskGo .26s var(--ease) .12s backwards}

@keyframes slAskOpen{
  from{flex-basis:0;opacity:0;border-color:transparent}
  40%{opacity:1}
  to{flex-basis:104px;opacity:1}
}
@keyframes slAskInk{from{opacity:0;transform:translateX(-7px)}to{opacity:1;transform:none}}
@keyframes slAskGo{from{opacity:0;transform:scale(.94)}to{opacity:1;transform:none}}

/* Уход: место возвращается имени, поле схлопывается туда же, откуда
   вышло. `forwards` держит его закрытым до следующей перерисовки. */
.sl-add.out .sl-add-price,.sl-add.out .sl-add-go{display:flex;pointer-events:none}
.sl-add.out .sl-add-price{animation:slAskShut .16s var(--ease) forwards;overflow:hidden}
.sl-add.out .sl-add-go{animation:slAskGoShut .12s var(--ease) forwards}
@keyframes slAskShut{
  from{flex-basis:104px;opacity:1}
  to{flex-basis:0;opacity:0;border-color:transparent}
}
@keyframes slAskGoShut{from{opacity:1}to{opacity:0;width:0;padding:0;margin:0;border-width:0}}

@media (prefers-reduced-motion:reduce){
  .sl-add.in .sl-add-price,.sl-add.in .sl-add-price>*,.sl-add.in .sl-add-go{animation:none}
  .sl-add.out .sl-add-price,.sl-add.out .sl-add-go{display:none;animation:none}
}

.sl-add-name{
  position:relative;display:flex;align-items:center;flex:1;min-width:0;
  border:1px solid var(--rule);border-radius:var(--r-sm);background:var(--card);transition:var(--t-tap) var(--ease);transition-property:border-color,box-shadow;
}
.sl-add-name>svg{position:absolute;left:11px;color:var(--ink-3);pointer-events:none}
.sl-add-name input{
  flex:1;min-width:0;padding:10px 12px 10px 34px;border:0;background:none;outline:none;
  font-size:13.5px;color:var(--ink);
}
.sl-add-price{
  position:relative;display:flex;align-items:center;flex:0 0 104px;
  border:1px solid var(--rule);border-radius:var(--r-sm);background:var(--card);transition:var(--t-tap) var(--ease);transition-property:border-color,box-shadow;
}
.sl-add-price input{
  width:100%;padding:10px 26px 10px 12px;border:0;background:none;outline:none;text-align:right;
  font-size:13.5px;letter-spacing:-.01em;color:var(--ink);
}
.sl-add-price span{
  position:absolute;right:11px;font-size:12px;color:var(--ink-3);
  pointer-events:none;
}
.sl-add-name:focus-within,.sl-add-price:focus-within{
  border-color:var(--ink);box-shadow:0 0 0 3px var(--focus-ring);
}
.sl-add input::placeholder{color:var(--ink-3)}
.sl-add-go{flex:0 0 auto;padding:0 15px;font-size:12px}
.sl-add-go[disabled]{opacity:.35;pointer-events:none}

/* Заголовок группы справочника — тот же, что в карточке брони: продавец
   один, и раскладка перед ним должна быть одна. */
.sl-pick-g{
  display:flex;align-items:center;gap:9px;margin:13px 0 7px;
  font-size:11px;font-weight:500;
  color:var(--ink-3);
}
.sl-pick-g::after{content:"";flex:1;height:1px;background:var(--rule-2)}
.sl-picks{display:grid;grid-template-columns:repeat(3,1fr);gap:7px;align-items:stretch}
.sl-pick{
  position:relative;display:flex;flex-direction:column;gap:3px;padding:9px 11px;text-align:left;
  border:1px solid var(--rule);border-radius:var(--r-sm);background:var(--card);transition:var(--t-tap) var(--ease);transition-property:background-color,border-color,transform;
}
.sl-pick span{
  font-size:12px;font-weight:550;letter-spacing:-.015em;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.sl-pick u{
  font-size:11px;letter-spacing:-.01em;color:var(--ink-3);
  text-decoration:none;
}
/* Строка «из чего сложилось» — только у того, что считается не штуками. */
.sl-pick em{
  margin-top:auto;padding-top:2px;font-style:normal;
  font-size:10px;letter-spacing:0;color:var(--ink-3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
/* В углу плитки по очереди живут две вещи: в покое — звезда избранного,
   под курсором — плюс. Плитка не выбирается, а сразу кладёт позицию
   в чек, и знак об этом предупреждает. */
.sl-pick i{
  position:absolute;top:7px;right:8px;display:flex;line-height:0;
  color:var(--ink-3);transition:opacity .12s;
}
.sl-pick::after{
  content:"+";position:absolute;top:6px;right:9px;font-size:13px;line-height:1;
  color:var(--accent);opacity:0;transition:opacity .12s;
}
@media (hover:hover) and (pointer:fine){
  .sl-pick:hover{border-color:var(--accent);background:var(--sunk)}
}
.sl-pick:hover::after{opacity:1}
.sl-pick:hover i{opacity:0}
.sl-pick.fav{border-color:var(--ink-3)}
@media (hover:hover) and (pointer:fine){
  .sl-pick:hover u{color:var(--ink-2)}
}
.sl-pick:active{transform:scale(.97)}
.sl-pick:focus-visible{outline:2px solid var(--ink);outline-offset:1px}
.sl-note-line{
  padding:11px 13px;border:1px dashed var(--rule);border-radius:var(--r);
  font-size:11.5px;line-height:1.45;color:var(--ink-3);
}

/* ── внесённое ──
   Способ, сумма и «Внести» отсюда ушли вместе с формой: деньги принимает
   общее окно (payment.css). Две формы для одного действия в одном окне —
   это не выбор, а развилка на ровном месте. */

/* Внесённое остаётся под рукой: ошибиться в кассе легко, и снять
   лишнюю оплату надо тем же движением, что и внести. */
.sl-paid{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.sl-chip{
  display:flex;align-items:center;gap:7px;padding:5px 6px 5px 11px;
  border-radius:var(--r-sm);background:var(--ok-bg);border:1px solid var(--ok-line);
}
.sl-chip b{font-size:11.5px;font-weight:550;color:var(--ok)}
.sl-chip u{
  font-size:12px;letter-spacing:-.01em;color:var(--ok);
  text-decoration:none;font-variant-numeric:tabular-nums;
}
.sl-chip button{display:flex;align-items:center;padding:2px;color:var(--ok);opacity:.55;transition:var(--t-tap) var(--ease);transition-property:color,opacity}
@media (hover:hover) and (pointer:fine){
  .sl-chip button:hover{opacity:1;color:var(--late)}
}

.sl-note{
  width:100%;padding:10px 12px;border-radius:var(--r-sm);
  border:1px solid var(--rule);background:var(--card);resize:vertical;
  font-family:var(--font);font-size:13px;line-height:1.45;color:var(--ink);transition:var(--t-tap) var(--ease);transition-property:border-color,box-shadow;
}
.sl-note:focus{outline:none;border-color:var(--ink);box-shadow:0 0 0 3px var(--focus-ring)}
.sl-note::placeholder{color:var(--ink-3)}

/* ═══════════ Чек ═══════════
   Тёмное поле — та же приборная полоса, что несёт шахматку; на ней
   лежит бумага. Два уровня поверхности вместо одного и дают чеку
   вес документа. */
.sl-rail{
  display:flex;flex-direction:column;min-width:0;min-height:0;
  background:var(--band);padding:18px 20px 0;
}
.rc{
  position:relative;flex:0 1 auto;min-height:0;display:flex;flex-direction:column;
  filter:drop-shadow(0 10px 20px rgba(0,0,0,.28)) drop-shadow(0 2px 4px rgba(0,0,0,.2));
  transition:transform .3s cubic-bezier(.2,.8,.3,1);
}
/* Рваный край. Зубцы нарисованы SVG-плиткой, а не маской: маска на
   конических градиентах в части движков не срабатывает и молча даёт
   ровную линию — а ровная линия здесь не «чуть хуже», это уже не чек.
   Край есть и сверху, и снизу: ленту оторвали с двух сторон. */
.rc-top,.rc-bottom{height:7px;flex-shrink:0;background-repeat:repeat-x}
.rc-top{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='7'%3E%3Cpath d='M0 7h12V0L6 5 0 0z' fill='%23FCFBF7'/%3E%3C/svg%3E");
}
.rc-bottom{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='7'%3E%3Cpath d='M0 0h12v7L6 2 0 7z' fill='%23FCFBF7'/%3E%3C/svg%3E");
}
.rc-body{
  flex:1;min-height:0;overflow-y:auto;background:var(--tape);
  padding:16px 18px 18px;color:var(--ink);
}
.rc-head{text-align:center;padding-bottom:13px}
.rc-head b{
  display:block;font-family:var(--mono);font-size:11px;font-weight:500;letter-spacing:.16em;
  text-transform:uppercase;color:var(--ink);
}
.rc-head span{
  display:block;margin-top:4px;font-family:var(--mono);font-size:9.5px;letter-spacing:.02em;
  color:var(--ink-3);
}
/* Разделители чека — пунктир, а не сплошная линия: на кассовой ленте
   их именно так и печатают, и от полос интерфейса они этим отличаются. */
.rc-lines,.rc-total,.rc-pays,.rc-due,.rc-guest,.rc-comment,.rc-empty{
  border-top:1px dashed var(--rule);padding-top:11px;
}
.rc-lines{padding-bottom:11px}
/* Строка — две строки: сверху то, что переноситься не должно, снизу
   подпись. Раньше всё лежало одним переносимым рядом, и на узкой ленте
   сумма уезжала под название: при `flex-wrap` браузер сначала переносит
   и только потом сжимает, поэтому ни `min-width:0`, ни многоточие этого
   не предотвращали. */
.rc-line{display:flex;flex-direction:column}
.rc-main{display:flex;align-items:center;flex-wrap:nowrap;gap:0 7px;min-width:0}
.rc-line+.rc-line{margin-top:8px}
/* Номер позиции — моноширинный и тихий: он нужен, чтобы про строку можно
   было сказать «третью убери», а не чтобы его читали подряд. */
.rc-no{
  flex-shrink:0;width:12px;font-family:var(--mono);font-size:10px;font-style:normal;
  /* Был --ink-3: 3,02:1 при норме 4,5 для текста. Номер строки — такой
     же текст, как остальное, и читать его должны все. */
  letter-spacing:-.02em;color:var(--ink-2);font-variant-numeric:tabular-nums;
}
/* Название переносится, а не обрезается. Обрезанное «Дрова, вязан…» на
   чеке — не мелкая неточность: гость по нему не поймёт, что купил, и
   спорить с ним будет не о чем. Место под перенос есть всегда, места
   под многоточие — нет. */
.rc-name{
  flex:0 1 auto;min-width:0;font-size:12.5px;line-height:1.3;color:var(--ink);
  overflow-wrap:anywhere;
}
/* Отточие ведёт глаз от названия к сумме. На кассовой ленте его печатают
   ровно за этим: без него на длинном чеке взгляд попадает в чужую сумму. */
/* Отточие занимает только свободное место: `flex-basis:0` и `min-width:0`
   значат, что в тесной строке оно исчезает первым, а не выталкивает сумму
   на другую строку. На узкой ленте вести глаз всё равно недалеко. */
.rc-dots{
  flex:1 1 0;min-width:0;align-self:center;height:1px;margin:0 1px;
  background-image:radial-gradient(circle, var(--ink-3) .8px, transparent .9px);
  background-size:4px 1px;background-repeat:repeat-x;opacity:.5;
}
.rc-line u{
  margin:1px 0 0 19px;font-family:var(--mono);font-size:10.5px;
  letter-spacing:-.02em;color:var(--ink-2);text-decoration:none;
}
.rc-line b{
  font-family:var(--mono);font-size:12.5px;font-weight:500;letter-spacing:-.035em;
  color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap;
}
/* Количество меняют прямо в чеке: отдельного окна ради «минус один» быть
   не должно. Знаки выходят под курсором, чтобы в покое чек оставался
   документом, а не панелью с кнопками. */
/* Количество видно всегда, а не по наведению.
   Пряталось оно ради «чек — документ, а не панель с кнопками», и ценой
   этому была нулевая ширина блока в покое: сколько штук пробито,
   приходилось узнавать наведением, а кнопки при этом сплющивались до
   9×19 px. Считать деньги наощупь нельзя, и никакой документ не важнее
   числа в нём.

   Тихими кнопки остаются иначе — волосяной рамкой в тоне бумаги, без
   заливки: они присутствуют, но не кричат. */
.rc-qty{display:flex;align-items:center;gap:2px;flex:0 0 auto;margin:0 2px}
.rc-qty button{
  position:relative;width:22px;height:22px;border-radius:var(--r-sm);
  border:1px solid var(--rule);background:var(--tape);color:var(--ink-2);
  font-size:14px;line-height:1;transition:var(--t-tap) var(--ease);transition-property:color,background-color,border-color,transform;
}
/* Нажимают больше, чем нарисовано: 22 px рисуем, 32 px нажимаем. Шаг
   строк — те же 32 px, поэтому области соседних строк не перекрываются.
   Каждый отнятый у кнопок пиксель уходит названию: на узкой ленте оно
   борется за место именно с ними. */
.rc-qty button::after{content:"";position:absolute;inset:-5px}
@media (hover:hover) and (pointer:fine){
  .rc-qty button:hover{border-color:var(--ink-3);background:var(--sunk);color:var(--ink)}
}
.rc-qty button:active{transform:scale(.92)}
.rc-qty button:focus-visible{outline:2px solid var(--ink);outline-offset:1px}
/* Число — чернилами и моноширинно: это показание, а не подпись. */
.rc-qty i{
  min-width:18px;text-align:center;font-family:var(--mono);font-size:12px;font-style:normal;
  font-weight:500;letter-spacing:-.03em;color:var(--ink);font-variant-numeric:tabular-nums;
}
.rc-empty{
  padding-bottom:11px;text-align:center;font-size:11.5px;line-height:1.5;color:var(--ink-3);
}

.rc-total{display:flex;align-items:baseline;gap:10px;padding-bottom:11px}
.rc-total span{
  flex:1;font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-3);
}
.rc-total b{
  font-family:var(--mono);font-size:15px;font-weight:500;letter-spacing:-.04em;color:var(--ink);
  font-variant-numeric:tabular-nums;
}

.rc-pays{padding-bottom:11px}
.rc-pay{display:flex;align-items:baseline;gap:10px}
.rc-pay+.rc-pay{margin-top:7px}
.rc-pay span{flex:1;min-width:0;font-size:12px;color:var(--ink-2)}
.rc-pay b{
  font-family:var(--mono);font-size:12.5px;font-weight:500;letter-spacing:-.035em;
  color:var(--ok);font-variant-numeric:tabular-nums;
}

.rc-tail{padding-bottom:2px}
.rc-due{display:flex;align-items:baseline;gap:10px;padding-bottom:11px}
.rc-due span{
  flex:1;font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-2);
}
.rc-due b{
  font-family:var(--mono);font-size:19px;font-weight:500;letter-spacing:-.05em;color:var(--ink);
  font-variant-numeric:tabular-nums;
}
.rc-due.zero span,.rc-due.zero b{color:var(--ok)}
.rc-due.change span,.rc-due.change b{color:var(--wait)}
.rc-guest b{display:block;font-size:12.5px;font-weight:600;color:var(--ink)}
.rc-guest span{display:block;margin-top:2px;font-size:11px;color:var(--ink-3)}
.rc-guest{padding-bottom:11px}
.rc-comment{font-size:11.5px;line-height:1.45;color:var(--ink-2);font-style:italic}
/* Под закрытым чеком оставлено поле: печать ложится на бумагу, а не
   поверх строк — перечёркнутое примечание читается как ошибка вёрстки. */
.rc.paid .rc-body{padding-bottom:62px}

/* Штамп ставят на бумагу, а не рисуют в макете: он повёрнут, полупрозрачен
   и лежит поверх строк — как настоящая печать. */
.rc-stamp{
  position:absolute;right:16px;bottom:26px;pointer-events:none;
  padding:5px 13px;border:2px solid var(--ok);border-radius:var(--r-xs);
  font-family:var(--mono);font-size:12px;font-weight:600;letter-spacing:.2em;
  text-transform:uppercase;color:var(--ok);opacity:.62;transform:rotate(-8deg);
}

.sl-act{
  margin-top:auto;padding:16px 0 18px;flex-shrink:0;
  display:flex;flex-direction:column;gap:4px;
}
/* Светлая кнопка на тёмной ленте чека. Текст — цветом ленты, а не акцентом:
   в тёмной теме акцент светлый и совпадал с фоном кнопки. */
.sl-punch{
  width:100%;background:var(--band-ink);color:var(--band);font-weight:600;
  transition:background-color var(--t-tap) var(--ease),transform var(--t-tap) var(--ease);
}
@media (hover:hover) and (pointer:fine){
  .sl-punch:hover{background:var(--plate-hi)}
}
.sl-punch:active{transform:scale(.985)}
.sl-punch[disabled]{
  background:none;color:var(--band-ink-3);box-shadow:inset 0 0 0 1px var(--band-3);
  pointer-events:none;
}
.sl-cancel{
  padding:8px;border-radius:var(--r-sm);font-size:12px;font-weight:500;
  color:var(--band-ink-3);transition:var(--t-tap) var(--ease);transition-property:color;
}
@media (hover:hover) and (pointer:fine){
  .sl-cancel:hover{color:var(--band-ink)}
}

/* ═══════════ Печать оплаты ═══════════
   Микро-история в три такта: строка приходит оттуда, откуда пришли
   деньги (слева, из кассы) → бумага под ней сдвигается вниз, потому что
   стала длиннее → остаток пересчитывается, и если он закрыт, на чек
   ложится печать.

   Движение здесь не украшение: без него новая строка просто возникает,
   и продавец не видит, изменилась ли сумма — а в кассе это ровно тот
   вопрос, ради которого он смотрит на экран.

   Такты уложены в 460 мс: дольше — и касса начнёт ждать анимацию.  */
@keyframes rc-pay-in{
  0%  {opacity:0;transform:translate3d(-20px,0,0)}
  62% {opacity:1;transform:translate3d(2px,0,0)}
  100%{opacity:1;transform:none}
}
/* Хвост чека едет из прежнего положения в новое: бумага выросла ровно
   на высоту строки, и глаз должен это увидеть, а не достроить. */
@keyframes rc-tail-down{ from{transform:translate3d(0,-26px,0)} }
/* Остаток не исчезает и не появляется заново — он перепечатывается.
   Гасить его в ноль было ошибкой: на первой трети движения строки
   «сколько ещё должны» на чеке не было вовсе, а это единственное, ради
   чего на чек в этот момент и смотрят. */
@keyframes rc-due-in{ from{opacity:.3;transform:translate3d(0,-5px,0)} }
@keyframes rc-stamp-in{
  0%  {opacity:0;transform:rotate(-24deg) scale(1.5)}
  70% {opacity:.72;transform:rotate(-5deg) scale(.94)}
  100%{opacity:.62;transform:rotate(-8deg) scale(1)}
}
/* Бумага коротко подаётся вверх — то же, что делает лента, когда
   принтер её протягивает. Третий, фоновый слой движения. */
@keyframes rc-fade-in{ from{opacity:0} }
@keyframes rc-feed{
  0%  {transform:translate3d(0,0,0)}
  35% {transform:translate3d(0,-3px,0)}
  100%{transform:translate3d(0,0,0)}
}

.rc-pay.fresh{animation:rc-pay-in .32s cubic-bezier(.2,.8,.3,1) both}
.rc-tail.shift{animation:rc-tail-down .34s cubic-bezier(.2,.8,.3,1) both}
.rc-tail.shift .rc-due{animation:rc-due-in .22s cubic-bezier(.2,.8,.3,1) both .09s}
/* Бумага подаётся не в момент нажатия, а когда щепка долетела:
   задержку ставит скрипт, она равна длине полёта. */
.rc.printing{animation:rc-feed .38s cubic-bezier(.4,0,.2,1) var(--land,0ms) both}
/* Строка проступает на бумаге. `backwards` — не приём: свёрнутой она
   бывает только до начала печати, а после — обычной строкой чека. Нет
   движения — есть строка: невидимых позиций в чеке не бывает. */
.rc-line.landing{animation:rc-line-in .26s var(--ease) var(--land,0ms) backwards}
@keyframes rc-line-in{
  from{height:0;margin-top:0;opacity:0;transform:translateY(-5px);overflow:hidden}
  to  {height:var(--h);margin-top:8px;opacity:1;transform:translateY(0);overflow:hidden}
}
.rc.printing.paid .rc-stamp{animation:rc-stamp-in .34s cubic-bezier(.175,.885,.32,1.275) both .12s}

/* Сокращённое движение — не «никакого движения»: строка всё равно должна
   появиться заметно, иначе непонятно, прошла оплата или нет. */
@media (prefers-reduced-motion:reduce){
  .rc-pay.fresh{animation:rc-fade-in .18s ease both}
  .rc-tail.shift,.rc-tail.shift .rc-due,.rc.printing,.rc-line.landing{animation:none}
  .rc.printing.paid .rc-stamp{animation:rc-fade-in .2s ease both}
  .sl-card:active,.sl-pick:active,.sl-method:active,
  .sl-pay-go:active,.sl-punch:active{transform:none}
}

@media (max-width:880px){
  .sl-main{grid-template-columns:1fr;overflow-y:auto}
  .sl-left{border-right:0;border-bottom:1px solid var(--rule)}
  .sl-form{overflow:visible}
  .sl-rail{padding-bottom:0}
  .rc-body{overflow:visible}
}

.sl-pick-rest{margin-top:9px;font-size:11px;line-height:1.45;color:var(--ink-3)}

/* ── позиция уезжает в чек ──
   Бумажная щепка: отрывается от плитки, летит дугой и печатается строкой.
   Набрана она уже по-чековому — моноширинной суммой на бумаге, — поэтому
   в момент посадки подменять нечего: щепка и строка выглядят одинаково.
   Лежит она поверх всего и курсор не ловит: это след движения, а не
   предмет, на который можно нажать. */
.rc-fly{
  position:fixed;z-index:120;pointer-events:none;
  display:flex;align-items:baseline;gap:8px;
  padding:5px 10px;border-radius:var(--r-sm);
  background:var(--tape);border:1px solid var(--rule);
  will-change:transform,opacity;
}
.rc-fly span{
  flex:1;min-width:0;font-size:12px;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.rc-fly b{
  font-family:var(--mono);font-size:12px;font-weight:500;letter-spacing:-.035em;
  color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap;
}
/* Строка, в которую только что попали: чернила ложатся и высыхают.
   Держится она недолго — это отметка события, а не состояние. */
.rc-line.inked{animation:rc-ink .42s var(--ease) both}
@keyframes rc-ink{
  0%  {background:rgba(var(--ink-rgb),.07)}
  100%{background:rgba(var(--ink-rgb),0)}
}
@media (prefers-reduced-motion:reduce){
  .rc-fly{display:none}
  .rc-line.inked{animation:rc-fade-in .18s ease both}
}

/* ── итог ──────────────────────────────────────────────────────
   Плашка на месте кнопки, а не поверх чека: чек — то, что сделали, и
   прятать его ради сообщения о нём незачем. Она встаёт туда, откуда
   ушло действие, и отвечает на два вопроса сразу: чем кончилось и что
   дальше.

   Исходов два, и различает их не только слово. Закрытый деньгами —
   зелёный: сделка кончилась здесь. Записанный в счёт — тон ожидания:
   она продолжится при выезде. */
.sl-done{
  margin-top:auto;padding:17px 18px 18px;flex-shrink:0;
  display:grid;grid-template-columns:auto 1fr;gap:2px 14px;align-items:center;
  border-radius:var(--r);background:var(--card);
  border:1px solid var(--rule);
}
.sl-done i{
  grid-row:1 / span 2;display:flex;align-items:center;justify-content:center;
  width:46px;height:46px;border-radius:50%;flex-shrink:0;
}
.sl-done.paid i{background:var(--ok-bg);color:var(--ok)}
.sl-done.billed i{background:var(--wait-bg);color:var(--wait)}
.sl-done b{font-size:15.5px;font-weight:600;letter-spacing:-.03em;color:var(--ink)}
.sl-done span{font-size:12px;line-height:1.4;color:var(--ink-2)}
.sl-done-go{grid-column:1 / -1;margin-top:15px}
.sl-done-go .btn{width:100%;min-height:44px}
.sl-done-go .sl-cancel{width:100%;margin-top:4px}

/* ── как она появляется ──
   Порядок тот же, каким её читают: сперва встаёт сама плашка — на месте
   ушедшей кнопки, снизу, тем же путём, — потом в круге рисуется знак,
   и только следом проступают слова и то, что делать дальше.

   Знак именно рисуется, а не проявляется: видно, как его ставят, и это
   единственный момент в кассе, где движение говорит «готово». Отскока
   нет: сделка закрыта — это факт, а не радость. */
.sl-done{animation:slDone .34s cubic-bezier(.2,.8,.3,1) backwards}
@keyframes slDone{from{opacity:0;transform:translateY(14px)}}
.sl-done i{animation:slSeal .3s cubic-bezier(.2,.8,.3,1) backwards .08s}
@keyframes slSeal{from{opacity:0;transform:scale(.72)}}
.sl-done .sl-draw{
  stroke-dasharray:34;stroke-dashoffset:34;
  animation:slDraw .34s cubic-bezier(.35,.6,.25,1) forwards .16s;
}
@keyframes slDraw{to{stroke-dashoffset:0}}
.sl-done b{animation:slDoneUp .26s cubic-bezier(.2,.8,.3,1) backwards .14s}
.sl-done span{animation:slDoneUp .26s cubic-bezier(.2,.8,.3,1) backwards .19s}
.sl-done-go{animation:slDoneUp .26s cubic-bezier(.2,.8,.3,1) backwards .25s}
@keyframes slDoneUp{from{opacity:0;transform:translateY(6px)}}

/* Штамп на чеке ставится в тот же момент, что и знак в плашке: одно
   событие — один кадр, иначе они читаются как два. */
.rc-stamp.bill{border-color:var(--wait);color:var(--wait)}
.rc-stamp{animation:rc-stamp-in .34s cubic-bezier(.175,.885,.32,1.275) backwards .16s}

@media (prefers-reduced-motion:reduce){
  .sl-done,.sl-done i,.sl-done b,.sl-done span,.sl-done-go,.rc-stamp{
    animation:rc-fade-in .2s ease backwards;animation-delay:0s;
  }
  /* Знак не рисуется, а стоит: движение убрано, сообщение осталось. */
  .sl-done .sl-draw{animation:none;stroke-dashoffset:0}
}


/* ── промокод в чеке ──
   Поле — в форме, рядом с примечанием; на ленте чека код стоит строкой со
   знаком минус перед итогом: скидка не поступление, зелёного ей нет. */
.sl-promo input{
  width:100%;height:34px;padding:0 11px;border:1px solid var(--rule);border-radius:var(--r-sm);
  background:var(--card);color:var(--ink);font:inherit;font-family:var(--mono);font-size:13px;
  letter-spacing:.04em;text-transform:uppercase;transition:border-color var(--t-tap) var(--ease);
}
.sl-promo input::placeholder{font-family:var(--font);letter-spacing:0;text-transform:none;color:var(--ink-3)}
.sl-promo input:focus{outline:none;border-color:var(--ink)}
.sl-promo-state{margin:6px 0 0;font-size:11.5px;line-height:1.4}
.sl-promo-state.ok{color:var(--ok)}
.sl-promo-state.err{color:var(--late)}
.rc-promo{
  display:flex;align-items:baseline;justify-content:space-between;gap:10px;
  padding:6px 0 2px;font-family:var(--mono);font-size:12px;color:var(--ink-2);
}
.rc-promo span{display:flex;flex-direction:column;gap:1px}
.rc-promo s{text-decoration:none;font-family:var(--font);font-size:10.5px;color:var(--ink-3)}
.rc-promo b{font-weight:500;letter-spacing:-.03em;color:var(--ink);white-space:nowrap}

/* «в справочник» у позиции, вписанной руками: слово под строкой, не кнопка. */
.rc-keep{
  display:inline-block;margin:2px 0 0 30px;font-size:10.5px;color:var(--ink-3);border-bottom:1px dotted var(--rule);
  transition:color var(--t-tap) var(--ease),border-color var(--t-tap) var(--ease);
}
@media (hover:hover) and (pointer:fine){
  .rc-keep:hover{color:var(--ink);border-bottom-color:var(--ink-3)}
}
.rc-keep:focus-visible{outline:2px solid var(--ink);outline-offset:2px;border-radius:2px}
