/* ============================================================
   «Остатки» — переиспользуемый виджет портала (js/ui/ostatki/).

   Все классы с приставкой `os-`, все токены — `--os-*`: виджет живёт внутри
   чужой страницы и не имеет права задеть соседей ни одним именем.

   ВИЗУАЛЬНЫЙ ЯЗЫК — СТРОКА ОРДЕРА BYBIT (владелец 14.09.2026: «сделать его
   похожим на то, как сделаны выплаты у байбита»): плашка статуса слева
   фиксированной колонкой, крупная сумма с логотипом банка и реквизитом
   посередине, мета точками ниже, действие справа. Повторён ЯЗЫК, а не файл:
   правила `.by-*` сюда не подключаются (сторож `ostatki_widget` следит, что в
   файле только свои классы).

   АНИМАЦИИ СТРОК ЗДЕСЬ НЕ ЖИВУТ. У владельца системно включён
   `prefers-reduced-motion`, и css-анимации он не увидит вовсе — появление,
   уход и перестановка идут Web Animations из `index.js` (правило 19.08.2026
   «вспышки нет, движение можно»). В CSS остаются только `transition`
   наведения: переходы браузер не глушит.

   ТОКЕНЫ ВЫВЕДЕНЫ ИЗ ПОРТАЛЬНЫХ, а не заданы цветом: виджет живёт ВНУТРИ
   страницы и обязан менять тему вместе с ней (в отличие от стакана, у которого
   своя тема со своим переключателем). Там, где производного значения мало,
   правка делается для светлой темы отдельно — по `[data-theme="light"]` на
   корне документа.

   Корней токенов ШЕСТЬ. Узлы вне поддерева `.os` токенов виджета не
   получают — значит, объявляют свои:
   • `.os` — сам виджет;
   • `.os-layer` — окно выбора макета раздела Bybit (модальное, в `body`);
   • `.os-slot` — слот в разделе Bybit (стоит ВЫШЕ `.os` в дереве);
   • `.os-chips` — чипы в ЧУЖОЙ шапке колонки «Покупка»;
   • `.os-pop` — раскрывающийся список ордеров Bybit (в `body`);
   • `.os-float` — плавающее окно расписки (в `body`, 19.09.2026).
   В `body` — потому что у оболочки `.content` стоит `transform` (контекст
   наложения), и `position: fixed` внутри страницы ведёт себя не так, как
   ждёшь. Токен, объявленный только на `.os`, в правилах этих узлов не
   разрешался бы, и строка с `var(--os-*)` молча становилась бы
   недействительной целиком.
   ============================================================ */

.os,
.os-layer,
.os-slot,
.os-chips,
.os-pop,
.os-float {
  --os-fg: var(--text);
  --os-fg2: var(--muted);
  --os-line: var(--border);
  --os-panel: var(--page-bg-2);
  --os-ctl: rgba(255, 255, 255, .06);
  --os-hov: rgba(255, 255, 255, .09);
  --os-accent: var(--primary);
  --os-ok: var(--primary);
  --os-amber: #e8b33a;
  --os-bad: #ff6b6b;
  /* Подложка копируемого: покой — еле заметная, наведение и нажатие — с
     акцентом. Не подчёркивание (владелец 14.09.2026), но и не вспышка. */
  --os-copy-bg: color-mix(in srgb, var(--os-fg) 7%, transparent);
  --os-copy-hov: color-mix(in srgb, var(--os-accent) 16%, transparent);
  --os-copy-on: color-mix(in srgb, var(--os-accent) 26%, transparent);
  --os-radius: 12px;
  --os-shadow: 0 18px 44px -16px rgba(0, 0, 0, .55);
}

[data-theme="light"] .os,
[data-theme="light"] .os-layer,
[data-theme="light"] .os-slot,
[data-theme="light"] .os-chips,
[data-theme="light"] .os-pop,
[data-theme="light"] .os-float {
  --os-ctl: rgba(15, 23, 42, .05);
  --os-hov: rgba(15, 23, 42, .08);
  /* В светлой теме та же доля тёмного текста читается грязным пятном. */
  --os-copy-bg: color-mix(in srgb, var(--os-fg) 5%, transparent);
  --os-amber: #a9761a;
  --os-bad: #d0402f;
  --os-shadow: 0 18px 44px -16px rgba(15, 23, 42, .2);
}

/* Виджет и окно сами отвечают за `hidden`: у вкладок и меток стоит display,
   и атрибут без этого правила перестал бы что-либо значить. */
.os [hidden],
.os-layer [hidden],
.os-float [hidden] {
  display: none !important;
}

/* ---------- каркас ---------- */

.os {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
  height: 100%;
  color: var(--os-fg);
  font-size: 13px;
}

.os * {
  box-sizing: border-box;
}

.os-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

/* ---------- сегменты (кнопками, не <select>) ----------

   Нативный `<select>` здесь запрещён: портальный `customSelect` улучшает
   КАЖДЫЙ селект страницы, растягивая его на 100% ширины, — компактному
   переключателю это смерть (ловушка 1 проекта). */

.os-seg {
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  background: var(--os-ctl);
  border-radius: 999px;
}

.os-seg > button {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  /* Тач-высота `button` из mobile.css (40px) сюда не пускается: сегмент
     тонкий, и на телефоне превратился бы в блок в пол-экрана. Правило стоит
     ВНЕ media-запроса — специфичность 0,1,0 выигрывает при любом порядке
     файлов (ловушка 5 проекта). */
  min-height: 0;
  height: 24px;
  padding: 0 10px;
  font: inherit;
  font-size: 12px;
  color: var(--os-fg2);
  background: transparent;
  border: 0;
  border-radius: 999px;
  cursor: pointer;
  white-space: nowrap;
  transition: color .15s ease, background .15s ease;
}

.os-seg > button:hover {
  color: var(--os-fg);
  background: var(--os-hov);
}

.os[data-tab="active"] .os-seg[data-seg="tab"] > button[data-tab-set="active"],
.os[data-tab="paid"] .os-seg[data-seg="tab"] > button[data-tab-set="paid"],
.os[data-tab="done"] .os-seg[data-seg="tab"] > button[data-tab-set="done"],
.os[data-tab="summary"] .os-seg[data-seg="tab"] > button[data-tab-set="summary"] {
  color: var(--os-fg);
  background: var(--os-panel);
}

/* Порядок живых — два сегмента-кнопки (19.09.2026): «общая / сначала наши» и
   «старые / новые сверху». Выбранная кнопка — по `aria-pressed`, как у
   периода сводки: состояние видно и читалке экрана. */
.os-seg--sort > button[aria-pressed="true"] {
  color: var(--os-fg);
  background: var(--os-panel);
}

.os[data-filter="all"] .os-seg--filter > button[data-filter-set="all"],
.os[data-filter="new"] .os-seg--filter > button[data-filter-set="new"],
.os[data-filter="active"] .os-seg--filter > button[data-filter-set="active"] {
  color: var(--os-fg);
  background: var(--os-panel);
}

.os-seg__n {
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  color: var(--os-fg2);
}

.os-seg__n:empty {
  display: none;
}

/* ---------- шапка: метка неудачной доставки, связь, ошибка ---------- */

.os-flag {
  padding: 2px 8px;
  font-size: 11px;
  color: var(--os-bad);
  border: 1px solid var(--os-bad);
  border-radius: 999px;
  white-space: nowrap;
}

/* СТРОКА СВЯЗИ, а не возраст данных: данные «Остатков» свои, каждая запись
   будит хаб, и запаздывать им негде (вопрос владельца 14.09.2026). Поэтому
   здесь тихая точка при живом потоке и красные слова при обрыве. */
.os-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
  font-size: 11px;
  color: var(--os-fg2);
  white-space: nowrap;
}

.os-link::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--os-fg2);
}

.os-link.is-live::before {
  background: var(--os-ok);
}

.os-link.is-bad {
  color: var(--os-bad);
}

.os-link.is-bad::before {
  background: var(--os-bad);
}

.os-err {
  padding: 6px 10px;
  font-size: 12px;
  color: var(--os-bad);
  background: color-mix(in srgb, var(--os-bad) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--os-bad) 35%, transparent);
  border-radius: var(--os-radius);
}

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

.os-pane {
  min-width: 0;
  min-height: 0;
  flex: 1 1 auto;
  overflow: auto;
}

/* ДИНАМИЧЕСКИЕ РАЗМЕРЫ (слово владельца 14.09.2026). На широком экране строк в
   ряду столько, сколько влезает по 560 px; при сужении — одна, и `min()` не
   даёт минимуму вылезти за экран телефона. `position: relative` нужен уходу
   строки: она выводится из потока и гаснет на своём месте. */
.os-list {
  display: grid;
  position: relative;
  grid-template-columns: repeat(auto-fill, minmax(min(560px, 100%), 1fr));
  gap: 8px;
  min-width: 0;
}

.os-empty {
  grid-column: 1 / -1;
  padding: 18px 10px;
  font-size: 12px;
  color: var(--os-fg2);
  text-align: center;
}

/* ---------- строка ордера ---------- */

.os-row {
  min-width: 0;
  /* Свой контейнер запроса: узкой считается САМА СТРОКА, а не окно. В два
     столбца строка бывает уже экрана вдвое, и медиа-запрос по ширине окна
     складывал бы её невпопад. */
  container-type: inline-size;
  background: var(--os-panel);
  border: 1px solid var(--os-line);
  border-radius: var(--os-radius);
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease, box-shadow .15s ease;
}

.os-row:hover {
  background: var(--os-hov);
  border-color: color-mix(in srgb, var(--os-accent) 35%, var(--os-line));
  box-shadow: 0 6px 18px -12px rgba(0, 0, 0, .6);
}

.os-row[data-status="new"] {
  border-color: color-mix(in srgb, var(--os-accent) 40%, var(--os-line));
}

/* Чек тащат ИЗ ЧАТА ОРДЕРА прямо на строку принятой расписки — короткий путь
   «открыть окно и приложить разом». Подсветка — на строке под курсором, её
   ставит делегат в `drop.js`. */
.os-row--drop {
  border-color: var(--os-accent);
  background: color-mix(in srgb, var(--os-accent) 10%, var(--os-panel));
}

/* Строка расписки, открытой сейчас в плавающем окне (19.09.2026): окно может
   стоять где угодно, и чьё оно — видно по ленте. Обод, а не заливка: заливка
   карточки читалась бы вспышкой (правило 19.08.2026). */
.os-row[data-open="1"] {
  border-color: var(--os-accent);
  box-shadow: inset 3px 0 0 var(--os-accent);
}

/* Фокус возвращается на строку-источник после закрытия окна руками: с
   клавиатуры его видно, после клика мышью — нет. */
.os-row:focus,
.os-hrow:focus {
  outline: none;
}

.os-row:focus-visible,
.os-hrow:focus-visible {
  outline: 1px solid var(--os-accent);
  outline-offset: 1px;
}

/* Три колонки, как у строки ордера Bybit: статус | информация | действие. */
.os-row__line {
  display: grid;
  grid-template-columns: 92px minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  min-width: 0;
  padding: 8px 10px;
}

.os-ordStatus {
  justify-self: start;
  max-width: 100%;
  padding: 2px 8px;
  font-size: 11px;
  font-weight: 600;
  border-radius: 6px;
  color: var(--os-fg2);
  background: var(--os-ctl);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.os-ordStatus[data-st="new"] {
  color: var(--os-accent);
  background: color-mix(in srgb, var(--os-accent) 16%, transparent);
}

.os-ordStatus[data-st="active"] {
  color: var(--os-amber);
  background: color-mix(in srgb, var(--os-amber) 16%, transparent);
}

.os-ordStatus[data-st="paid"] {
  color: var(--os-ok);
  background: color-mix(in srgb, var(--os-ok) 16%, transparent);
}

.os-ordStatus[data-st="released"] {
  color: var(--os-bad);
  background: color-mix(in srgb, var(--os-bad) 14%, transparent);
}

.os-ordMid {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.os-ordTop {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.os-ordSum {
  flex: 0 0 auto;
  font-size: 15px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Значок банка — одно решение на портал (`ui/bankIcons.js`); плашка даётся
   точечно тем логотипам, которые без неё пропадают. */
.os-bank {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 5px;
  object-fit: contain;
}

.os-bank.is-plate,
.os-bank--mono {
  background: #f4f5f7;
}

.os-bank--mono {
  /* Цвет монограммы приходит инлайном от `ui/bankIcons.js` (один банк — один
     цвет во всех списках портала). Объявляем его здесь же с запасным
     значением: токен, которого нет ни в одном файле, ловит `css_tokens`. */
  --os-bank-c: #333;
  font-size: 11px;
  font-weight: 700;
  color: var(--os-bank-c);
}

.os-bank--none {
  background: var(--os-ctl);
}

/* Способ оплаты у ещё не принятой расписки — на месте реквизита. */
.os-ordWay {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--os-fg2);
}

.os-ordSub {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
  font-size: 11px;
  color: var(--os-fg2);
}

/* Точки-разделители, как в строке ордера Bybit: «команда X · ab12cd · 18:02».
   Точка живёт у последующего элемента: спрятался элемент — ушла и она. */
.os-ordSub > * + *::before {
  content: "· ";
  color: var(--os-fg2);
}

.os-ordSrc {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.os-ordWho,
.os-ordAt {
  flex: 0 0 auto;
  white-space: nowrap;
}

.os-ordAt {
  font-variant-numeric: tabular-nums;
}

/* Обратный отсчёт ВЫПЛАТЫ (владелец 20.09.2026) — тот же срок, что у оператора
   на «Метчинге», продолженный здесь. Цифры не должны дёргать строку по ширине
   каждую секунду: разряды моноширинные. */
.os-ordLeft {
  display: inline-flex;
  align-items: baseline;
  gap: 3px;
  flex: 0 0 auto;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* Значок отличает срок от времени создания, стоящего рядом той же цифрой. */
.os-ordLeft__i {
  font-size: 10px;
  line-height: 1;
  opacity: 0.75;
}

/* Сверх срока: «+1:23» и дальше растёт. Признак ставит тикер на узел с числом,
   а красится ячейка целиком — значок в стороне выглядел бы чужим. Цветом И
   весом: знак «+» читается и там, где цвет не различить. */
.os-ordLeft:has([data-over]) {
  color: var(--os-bad);
  font-weight: 600;
}

.os-ordActs {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  justify-self: end;
}

/* Узкая строка (не узкое окно!): статус уходит в первую линию к сумме,
   действие — под ними. Ничего не выезжает за край: каждый текстовый блок
   несёт min-width: 0 и обрезку. */
@container (max-width: 430px) {
  .os-row__line {
    grid-template-columns: minmax(0, 1fr) auto;
    row-gap: 6px;
  }

  .os-ordStatus {
    grid-column: 1 / -1;
  }

  .os-ordMid {
    grid-column: 1;
  }

  .os-ordActs {
    grid-column: 2;
  }
}

/* ---------- копирование ----------

   БЕЗ ПОДЧЁРКИВАНИЯ (владелец 14.09.2026: «чуть поправь у них визуал суммы и
   реквизита, чтобы не было подчеркнуто а красиво слегка выделялось чтобы было
   видно что можно копировать»). Раньше значение несло пунктирную черту снизу —
   она читалась как ссылка и рвала строку цифр. Теперь копируемое живёт на еле
   заметной подложке со скруглением: видно всегда, а под курсором подложка
   набирает цвет. Отрицательные внешние поля гасят собственные внутренние —
   иначе сумма съезжала бы от плашки статуса на ширину подложки.

   `min-height: 0` обязателен: `mobile.css` поднимает КАЖДОЙ кнопке портала
   min-height до 40 px ради тач-целей (ловушка 5 проекта), и копируемая сумма
   внутри строки превратилась бы на телефоне в блок. */

.os-copy {
  position: relative;
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  min-width: 0;
  min-height: 0;
  margin: 0 -5px;
  padding: 1px 5px;
  font: inherit;
  font-variant-numeric: tabular-nums;
  color: var(--os-fg);
  background: var(--os-copy-bg);
  border: 0;
  border-radius: 7px;
  cursor: copy;
  text-align: left;
  transition: background .15s ease, color .15s ease;
}

/* Под курсором значение ещё и проясняется: приглушённый номер выплаты
   (`.os-copy--id`) читается ровно тогда, когда его собрались копировать. */
.os-copy:hover {
  background: var(--os-copy-hov);
  color: var(--os-fg);
}

.os-copy:active {
  background: var(--os-copy-on);
}

.os-copy:focus-visible {
  outline: 1px solid var(--os-accent);
  outline-offset: 1px;
}

.os-copy--id {
  font-size: 11px;
  color: var(--os-fg2);
}

.os-copy__val {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Подпись «скопировано»: узел ставит и снимает `copyFlash`, движение — Web
   Animations (css-анимаций у владельца нет, см. шапку файла). Она ВНЕ потока и
   не ловит указатель — иначе строка дёргалась бы на каждом копировании. */
.os-copy__flash {
  position: absolute;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  z-index: 2;
  padding: 1px 7px;
  font-size: 10px;
  line-height: 1.5;
  white-space: nowrap;
  color: var(--os-accent);
  background: var(--os-panel);
  border: 1px solid color-mix(in srgb, var(--os-accent) 40%, transparent);
  border-radius: 999px;
  box-shadow: var(--os-shadow);
  pointer-events: none;
}

/* ---------- чипы ---------- */

.os-chip {
  display: inline-flex;
  align-items: center;
  max-width: 100%;
  padding: 1px 8px;
  font-size: 11px;
  color: var(--os-fg2);
  background: var(--os-ctl);
  border-radius: 999px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.os-chip[data-bad="1"] {
  color: var(--os-bad);
  background: color-mix(in srgb, var(--os-bad) 14%, transparent);
}

/* Не красный: придержанная доплата — это ОЖИДАНИЕ, а не неудача. Оплата
   прошла, чек лежит у сервера и ждёт, когда оператор отправит его вместе с
   чеками приёма (владелец 14.09.2026). */
.os-chip[data-hold="1"] {
  color: var(--os-amber);
  background: color-mix(in srgb, var(--os-amber) 16%, transparent);
}

.os-chip[data-chip="gone"] {
  color: var(--os-amber);
  background: color-mix(in srgb, var(--os-amber) 16%, transparent);
}

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

.os-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* См. пояснение у .os-seg > button: тач-высота отбивается адресно и ВНЕ
     media-запроса. */
  min-height: 0;
  height: 26px;
  padding: 0 12px;
  font: inherit;
  font-size: 12px;
  color: var(--os-fg);
  background: var(--os-ctl);
  border: 1px solid transparent;
  border-radius: 999px;
  cursor: pointer;
  white-space: nowrap;
  transition: background .15s ease;
}

.os-btn:hover:not(:disabled) {
  background: var(--os-hov);
}

.os-btn:disabled {
  opacity: .55;
  cursor: default;
}

.os-btn--primary {
  color: #06120b;
  background: var(--os-accent);
}

.os-btn--primary:hover:not(:disabled) {
  background: color-mix(in srgb, var(--os-accent) 85%, #ffffff);
}

.os-x {
  min-height: 0;
  width: 22px;
  height: 22px;
  padding: 0;
  font: inherit;
  font-size: 15px;
  line-height: 1;
  color: var(--os-fg2);
  background: transparent;
  border: 0;
  border-radius: 8px;
  cursor: pointer;
}

.os-x:hover {
  color: var(--os-fg);
  background: var(--os-hov);
}

/* Ссылка на чек — КНОПКА: файл качается с заголовком авторизации и
   показывается объектной ссылкой, голого href здесь быть не может (у сайта
   нет cookie, токен лежит в localStorage). */
.os-doc {
  min-height: 0;
  padding: 0;
  font: inherit;
  font-size: 12px;
  color: var(--os-accent);
  background: transparent;
  border: 0;
  border-bottom: 1px dashed color-mix(in srgb, var(--os-accent) 50%, transparent);
  cursor: pointer;
  white-space: nowrap;
}

/* ---------- вкладка «завершённые» ---------- */

.os-hist {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}

.os-hist__head {
  display: flex;
  gap: 8px;
  min-width: 0;
}

.os-input {
  width: 100%;
  min-width: 0;
  height: 30px;
  padding: 0 10px;
  font: inherit;
  font-size: 12px;
  color: var(--os-fg);
  background: var(--os-ctl);
  border: 1px solid var(--os-line);
  border-radius: 10px;
}

.os-input:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--os-accent) 55%, var(--os-line));
}

.os-hist__foot {
  display: flex;
  justify-content: center;
}

/* ЗАВЕРШЁННЫЕ — НЕ ПЛИТКИ (владелец 14.09.2026: «они нужны просто строками
   чтобы было компактней»): одноэтажные строки во всю ширину, колонки выровнены
   между собой сеткой, плиточная `auto-fill` осталась только у живых вкладок. */
.os-hist__list {
  display: flex;
  flex-direction: column;
  min-width: 0;
  /* Узкой считается САМА ЛЕНТА, а не окно: виджет стоит внутри страницы и
     бывает уже неё. В колонке строка равна ширине ленты, поэтому контейнером
     запроса назначена лента (сама себя элемент запросить не может). */
  container-type: inline-size;
}

/* Списанные USDT и курс (19.09.2026, ТЗ «Сводка остатков») — своими
   колонками сразу за суммой: по ним внешние команды считают долг, и строку
   сверяют с отчётом глазами. Каждая ячейка стоит в СВОЕЙ именованной области:
   пустая ячейка (нет USDT) держит место, а спрятанная на узкой ленте
   (`display: none` у курса) не сдвигает соседей — авторасстановки у сетки нет
   (ловушка 3 проекта). */
.os-hrow {
  display: grid;
  grid-template-columns: 84px auto 96px 60px minmax(0, 1.2fr) minmax(0, 1fr) auto 84px;
  grid-template-areas: "st sum usdt rate req src num at";
  align-items: center;
  gap: 10px;
  min-width: 0;
  padding: 5px 8px;
  border-bottom: 1px solid var(--os-line);
  cursor: pointer;
  transition: background .15s ease;
}

.os-hrow:hover {
  background: var(--os-hov);
}

/* Открытая сейчас в окне расписка — метка корешком, без заливки. */
.os-hrow[data-open="1"] {
  box-shadow: inset 3px 0 0 var(--os-accent);
}

.os-hrow__st { grid-area: st; }
.os-hrow__sum { grid-area: sum; }
.os-hrow__usdt { grid-area: usdt; }
.os-hrow__rate { grid-area: rate; }
.os-hrow__req { grid-area: req; }
.os-hrow__src { grid-area: src; }
.os-hrow__num { grid-area: num; }
.os-hrow__at { grid-area: at; }

.os-hrow__sum {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.os-hrow__usdt,
.os-hrow__rate {
  min-width: 0;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.os-hrow__rate {
  color: var(--os-fg2);
}

.os-hrow__req {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.os-hrow__reqText {
  min-width: 0;
  font-variant-numeric: tabular-nums;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.os-hrow__src {
  min-width: 0;
  font-size: 12px;
  color: var(--os-fg2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.os-hrow__num {
  min-width: 0;
}

.os-hrow__at {
  font-size: 11px;
  color: var(--os-fg2);
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

/* ---------- модальный слой в body: окно выбора макета раздела Bybit ----------

   Окном расписки `.os-layer` больше не служит (с 19.09.2026 оно плавающее,
   `.os-float` ниже) — остался одному окну выбора макета (`bybit.page.js`).
   Этаж фиксированный и ниже окна ордера Bybit (`.bw-win`, 10010): из стека
   слоёв (BASE_Z 10020) его брать нельзя — первая карточка ордера этаж из
   стека НЕ получает, и стековые 10020 накрыли бы её. */

.os-layer {
  position: fixed;
  inset: 0;
  z-index: 10005;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  color: var(--os-fg);
  font-size: 13px;
}

.os-layer__back {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, .5);
}

/* ---------- окно расписки: ПЛАВАЮЩЕЕ (решение владельца 19.09.2026) ----------

   Немодальное: ни подложки, ни затемнения, ни места в стеке слоёв — под
   окном кликается всё (список остатков, колонки «Продажа/Покупка», карточка
   ордера Bybit, мини-чат, откуда тащат чек). Место ставит `floatFrame.js`
   инлайном в px (`left/top`), высоту ограничивает по нижний край рабочей
   области (`max-height` инлайном): тело `.os-win` прокручивается внутри, и
   подвал с «оплачено» не уходит за экран.

   ЭТАЖ 10004 — ниже окна выбора макета (10005), списка ордеров `.os-pop`
   (10006) и карточки ордера Bybit `.bw-win` (10010): карточка, открытая
   оповещением, обязана лечь поверх окна, а не под него.

   Окно само себе КОНТЕЙНЕР (`oswin`): узкие правила ниже мерят окно, а не
   экран — на телефоне окно во весь экран, на широком — 640 px. Двухколоночный
   вид 14.09 снят тем же решением владельца: окно только узкое. */

.os-float {
  position: fixed;
  z-index: 10004;
  /* До первого `place()` — правый низ экрана; дальше `left/top` инлайном. */
  right: 16px;
  bottom: 16px;
  display: flex;
  flex-direction: column;
  width: min(640px, calc(100vw - 16px));
  max-height: calc(100vh - 16px);
  color: var(--os-fg);
  font-size: 13px;
  container-type: inline-size;
  container-name: oswin;
}

/* Окно берёт программный фокус на открытии (якорь Escape, `tabindex="-1"`):
   своего контура у него нет — поля и кнопки внутри свой фокус показывают
   (жалоба владельца 14.09.2026 на «выделение непонятно чего»). */
.os-float:focus,
.os-float:focus-visible {
  outline: none;
}

/* ОКНО ЦЕЛИКОМ — зона броска (владелец 20.09.2026: «возможность перетаскивать
   чек PDF и скрин отмены должны быть обязательно»). Зона чека невелика, а
   файл тащат из ленты чата — промахнуться легко, поэтому подсвечивается всё
   окно, и видно, что бросок примут. Что именно оно ждёт, решает режим: в
   отказе — картинку, иначе — PDF. */
.os-float.is-dropping > .os-win {
  border-color: var(--os-accent);
  box-shadow: var(--os-shadow), inset 0 0 0 1px color-mix(in srgb, var(--os-accent) 45%, transparent);
}

.os-win {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 100%;
  /* Потолок держит `.os-float` (инлайн от `floatFrame.js`): тело сжимается
     под него и прокручивается внутри. */
  flex: 0 1 auto;
  min-height: 0;
  overflow: auto;
  padding: 14px;
  /* Окну поверх страницы нужен НЕПРОЗРАЧНЫЙ фон: --card-bg это плёнка, сквозь
     неё просвечивает страница (правило проекта). */
  background: var(--os-panel);
  border: 1px solid var(--os-line);
  border-radius: 16px;
  box-shadow: var(--os-shadow);
}

/* ШАПКА — ручка переноса и всегда на виду: тело прокручивается под ней, а
   «×» и перенос не уезжают за верх. Отрицательные поля растягивают её на всю
   ширину окна поверх собственных отступов, фон закрывает текст под ней.
   `touch-action: none` отдаёт жест пальцем переносу, а не прокрутке страницы;
   `user-select: none` — чтобы перенос не выделял текст шапки. */
/* ШАПКА НЕ ПЕРЕНОСИТСЯ (владелец 20.09.2026: «крестик перенёсся на следующую
   строку, ему не хватило места»). При переносе крестик и тумблер уезжали на
   второй этаж — то есть кнопка закрытия оказывалась не там, где её ищут.
   Теперь строка одна, а тесно становится ВНУТРЕННЕМУ номеру расписки: он
   ужимается с многоточием (правило ниже). */
.os-win__head {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 10px;
  min-width: 0;
  margin: -14px -14px 0;
  padding: 12px 14px 8px;
  background: var(--os-panel);
  cursor: grab;
  touch-action: none;
  user-select: none;
}

.os-float.is-dragging .os-win__head {
  cursor: grabbing;
}

/* Вопрос «переключиться на другую расписку?» — своим узлом под шапкой
   (`data-switch-ask`): замечание окна его бы стёрло. Тёплый, не красный:
   ничего не сломалось, нужен ответ. */
.os-win__ask {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  font-size: 12px;
  color: var(--os-amber);
  background: color-mix(in srgb, var(--os-amber) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--os-amber) 35%, transparent);
  border-radius: var(--os-radius);
}

.os-win__askText {
  flex: 1 1 220px;
  min-width: 0;
  overflow-wrap: anywhere;
}

.os-win__askActs {
  display: flex;
  flex: 0 0 auto;
  gap: 6px;
}

.os-win__sum {
  font-size: 18px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.os-win__spacer {
  flex: 1 1 auto;
  min-width: 0;
}

/* Кому уступать место в тесной шапке: внутреннему номеру расписки. Статус,
   сумма, тумблер и крестик не жмутся — их ищут глазами и пальцем. */
.os-win__head > .os-copy--id {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.os-win__head > .os-ordStatus,
.os-win__head > .os-win__sum,
.os-win__head > .os-tgl,
.os-win__head > .os-x {
  flex: 0 0 auto;
}

/* ТУМБЛЕР «закрывать окно после действия» — рядом с крестиком (владелец
   20.09.2026). Положение живёт на сервере, а не в браузере.

   Почему ОДИН `<input>`, а не `<label>` с текстом:
     • шапка — ручка переноса, и жест не начинается только с `button, a, input,
       [data-copy]` (`floatFrame.js`). Подпись рядом с полем сделала бы целью
       нажатия `<span>`, и окно поехало бы вместо переключения;
     • `mobile.css` поднимает ВСЕМ `button` высоту до 40 px ради тач-целей —
       тумблер, сделанный кнопкой, на телефоне стал бы блоком в пол-экрана
       (ловушка 5 из CLAUDE.md).
   Слова — в `title` и `aria-label`: в шапке рядом со статусом и суммой места
   под подпись нет. Переходов НЕТ: css-анимаций в разделе не заводим
   (`prefers-reduced-motion` у владельца включён). */
.os-tgl {
  appearance: none;
  position: relative;
  flex: 0 0 auto;
  width: 32px;
  height: 18px;
  margin: 0;
  padding: 0;
  background: color-mix(in srgb, var(--os-fg2) 22%, transparent);
  border: 1px solid var(--os-line);
  border-radius: 999px;
  cursor: pointer;
}

.os-tgl::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 12px;
  height: 12px;
  background: var(--os-fg2);
  border-radius: 50%;
}

.os-tgl:checked {
  background: color-mix(in srgb, var(--os-ok) 30%, transparent);
  border-color: color-mix(in srgb, var(--os-ok) 55%, transparent);
}

.os-tgl:checked::after {
  left: auto;
  right: 2px;
  background: var(--os-ok);
}

.os-tgl:disabled {
  cursor: default;
  opacity: .5;
}

.os-win__body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}

/* ДВЕ СЕКЦИИ ТЕЛА стоят друг под другом и дают РОВНО тот же порядок и те же
   отступы, что у одного столбца: тело — колонка с gap 12, каждая секция —
   колонка с тем же gap. Двухколоночный вид (14.09.2026) владелец снял
   19.09.2026 — окно только узкое; разметку секций не трогали. */
.os-win__left,
.os-win__right {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}

/* СВЕДЕНИЯ — СЕТКА В ДВА СТОЛБЦА (владелец 20.09.2026, опрос «сделать окно
   меньше»). До этого было одиннадцать строк по одной на поле — четверть высоты
   окна под то, что читают мельком. Пары встают рядом, а длинное (реквизит,
   путь, причина, текст заявки) занимает всю ширину — `.os-kv--wide`.

   Это НЕ двухколоночный вид, снятый владельцем 19.09.2026: там рядом вставали
   БЛОКИ окна (`left|right`), и работа с чеком уезжала вбок. Здесь блоки
   по-прежнему друг под другом, парами стоят только строки «ключ — значение».

   Один столбец, пока окну тесно: 520 px — ширина, ниже которой пара «подпись +
   значение» в половине окна уже рвётся. Запрос КОНТЕЙНЕРНЫЙ (`oswin`): виджет
   бывает уже экрана, и мерить надо окно. */
.os-win__info {
  display: grid;
  grid-template-columns: 1fr;
  gap: 4px 18px;
  min-width: 0;
}

@container oswin (min-width: 520px) {
  .os-win__info {
    grid-template-columns: 1fr 1fr;
  }

}

/* Во всю ширину: длинные значения и собственные блоки тела (заявка, дубль). */
.os-kv--wide,
.os-win__info > .os-target,
.os-win__info > .os-meta,
.os-win__info > .os-ext,
.os-win__info > .os-ext__ask,
.os-win__info > .os-ext__dup {
  grid-column: 1 / -1;
}

/* ЦЕЛЬ ПЛАТЕЖА — первой строкой и крупно (владелец 20.09.2026). Реквизит был
   одной из десяти одинаковых строк, хотя ради него окно и открывают. */
.os-target {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  min-width: 0;
  padding-bottom: 2px;
}

.os-target__num {
  font-size: 16px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: .01em;
  min-width: 0;
  overflow-wrap: anywhere;
}

/* Способ перевода — чипом: «карта» и «СБП» меняют смысл номера, но сами по
   себе не читаются. */
.os-target__way {
  flex: 0 0 auto;
  padding: 2px 8px;
  font-size: 11px;
  color: var(--os-fg2);
  background: var(--os-ctl);
  border-radius: 999px;
}

/* ВТОРОСТЕПЕННОЕ — одной строкой чипов вместо четырёх строк с подписями:
   источник, группа, автор, время, номер заявки читают мельком и вместе.
   Подпись ОСТАЁТСЯ внутри чипа приглушённой (`os-mchip__k`): голое «20.09
   17:18» среди соседей не говорит ничего, а `title` прячет её от всех, кто не
   водит мышкой (сторожа поймали ровно это 20.09.2026). */
.os-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.os-mchip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 100%;
  padding: 2px 8px;
  font-size: 11px;
  color: var(--os-fg);
  background: var(--os-ctl);
  border-radius: 999px;
  overflow-wrap: anywhere;
}

/* Подпись внутри чипа — приглушённой: значение читают, подпись подтверждает. */
.os-mchip__k {
  flex: 0 0 auto;
  color: var(--os-fg2);
}

a.os-mchip {
  text-decoration: none;
}

a.os-mchip:hover {
  color: var(--os-accent);
}

/* ПУТЬ расписки одной строкой вместо пяти («зафиксировала / приняла /
   оплатила / сняла / завершена»). Шаги переносятся, разделитель рисует сам
   CSS — в разметке его нет, иначе он остался бы висеть после переноса. */
.os-path {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 10px;
  min-width: 0;
}

.os-path__step {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  min-width: 0;
}

.os-path__step + .os-path__step::before {
  content: "→";
  color: var(--os-fg2);
}

.os-path__w {
  color: var(--os-fg2);
}

/* Секция — СЕТКА (20.09.2026): в узком окне один столбец и заголовок сверху,
   как было; от 520 px заголовок уходит влево, в свою колонку (правило выше). */
.os-win__sec {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 8px;
  min-width: 0;
  padding-top: 10px;
  border-top: 1px solid var(--os-line);
}

/* Подпись секции — ТА ЖЕ форма, что у подписей сведений (владелец 20.09.2026:
   «тяжело ориентироваться»): строчными, 12 px, приглушённая, в одну строку.
   Прописные 11 px с разрядкой были третьим способом подписать блок в одном
   окне — рядом с `.os-kv__k` и чипами. `nowrap` обязателен: «ордер Bybit» в
   узкой колонке переносился по словам и налезал на поле. */
.os-sec__head {
  font-size: 12px;
  color: var(--os-fg2);
  white-space: nowrap;
}

/* ЗАГОЛОВОК СЕКЦИИ — СЛЕВА ОТ СОДЕРЖИМОГО (владелец 20.09.2026).

   СТОИТ ЗДЕСЬ, ПОСЛЕ базовых правил, и это несущее: контейнерный запрос
   специфичности НЕ добавляет, решает ПОРЯДОК. В первой версии 20.09.2026 он
   стоял выше `.os-win__sec`, и базовое `grid-template-columns: minmax(0,1fr)`
   его перебивало: колонка заголовка схлопывалась в 16 px, «ОРДЕР BYBIT»
   переносился по буквам и налезал на поле (увидено в браузере 20.09.2026).
   Ровно эта ловушка описана в этом файле ещё двумя абзацами — и это третий
   раз, когда в неё наступили. */
@container oswin (min-width: 520px) {
  .os-win__sec {
    grid-template-columns: 116px minmax(0, 1fr);
    column-gap: 12px;
    align-items: start;
  }

  .os-win__sec > .os-sec__head {
    grid-column: 1;
    padding-top: 6px;
  }

  .os-win__sec > *:not(.os-sec__head) {
    grid-column: 2;
  }

  /* Ширину поля номера держит КОМБО: оно и есть флекс-элемент строки. */
  .os-pin > .os-combo {
    flex: 0 1 320px;
  }

  /* Текст заявки подписывается ТАК ЖЕ, как ордер и чек: подпись слева, блок
     справа. До 20.09.2026 его заголовок стоял над блоком во всю ширину — это
     был третий способ подписать блок в одном окне. */
  .os-win__info > .os-ext {
    display: grid;
    grid-template-columns: 116px minmax(0, 1fr);
    column-gap: 12px;
    align-items: start;
  }

  .os-win__info > .os-ext > .os-sec__head {
    padding-top: 6px;
  }

  /* В СЕТКЕ ширину держит `justify-self`, а не `align-self`: последний
     управляет блочной осью. В узком окне `.os-ext` остаётся флекс-колонкой,
     и там работает `align-self` из базового правила — нужны оба. */
  .os-win__info > .os-ext > .os-ext__text {
    justify-self: start;
  }
}


.os-win__err {
  padding: 6px 10px;
  font-size: 12px;
  color: var(--os-bad);
  background: color-mix(in srgb, var(--os-bad) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--os-bad) 35%, transparent);
  border-radius: var(--os-radius);
}

/* Замечание сервера — НЕ ошибка: оплата прошла, а ордер Bybit просто ещё не
   доехал в нашу базу. Красным такое красить нельзя (владелец 14.09.2026). */
.os-win__note {
  padding: 6px 10px;
  font-size: 12px;
  color: var(--os-amber);
  background: color-mix(in srgb, var(--os-amber) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--os-amber) 35%, transparent);
  border-radius: var(--os-radius);
}

.os-win__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  padding-top: 10px;
  border-top: 1px solid var(--os-line);
}

.os-foot__ask {
  flex: 1 1 auto;
  font-size: 12px;
  color: var(--os-amber);
}

/* ---------- строки «ключ — значение» ---------- */

.os-kv {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
  font-size: 12px;
}

/* Подпись уже, чем была (150 px): в половине окна на значение оставалось бы
   меньше места, чем на подпись к нему (20.09.2026). */
.os-kv__k {
  flex: 0 0 auto;
  width: 96px;
  color: var(--os-fg2);
}

.os-kv__v {
  flex: 1 1 160px;
  min-width: 0;
  overflow-wrap: anywhere;
}

.os-kv__req {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.os-kv__at {
  color: var(--os-fg2);
  font-variant-numeric: tabular-nums;
}

/* ---------- блок «Ордер Bybit» ---------- */

.os-pin {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  min-width: 0;
}

.os-pin__input {
  flex: 1 1 180px;
}

.os-pin__card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
  padding: 10px;
  background: var(--os-ctl);
  border-radius: var(--os-radius);
}

.os-pin__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.os-pin__num {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

.os-pin__grid {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.os-pin__acts {
  display: flex;
  justify-content: flex-end;
}

/* РУЧНОЕ закрепление: номера нет ни в базе портала, ни в живом кадре биржи —
   платили не с Bybit (владелец 15.09.2026). Строка живёт в разметке всегда и
   показывается атрибутом `hidden`: перерисовка блока под курсором теряла бы
   каретку в поле номера. Своя строка на всю ширину — она не продолжение поля,
   а отдельный вопрос. */
.os-pin__manual {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 8px;
  flex: 1 1 100%;
  min-width: 0;
}

.os-pin__usdt {
  flex: 0 1 220px;
  min-width: 0;
}

.os-pin__manualHint {
  flex: 1 1 160px;
  min-width: 0;
  font-size: 11px;
  color: var(--os-fg2);
}

/* Отказ закрепления — ПОД СВОИМ полем, а не в общей красной строке внизу
   окна: иначе он читается как отказ оплаты (владелец 14.09.2026). */
.os-pin__err {
  font-size: 12px;
  color: var(--os-bad);
}

.os-pin__hint,
.os-pay__hint {
  font-size: 11px;
  color: var(--os-fg2);
}

/* Дозакрепление у завершённой (19.09.2026): отчёт за прошедший период
   изменится — подпись тёплая, её обязаны прочесть до нажатия. */
/* Замена ордера у оплаченной/завершённой — обычная ручная правка (владелец
   19.09.2026: «считать как окей и не отображать жёлтым»): подпись без жёлтого. */
.os-pin__hint[data-late="1"] {
  color: var(--os-fg2);
}

/* ---------- блок чека ---------- */

.os-pay {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}

.os-pay__foot {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
}

/* Зона броска чека — ОДНОСТРОЧНАЯ (владелец 20.09.2026, опрос «такое большое
   поле для чека не нужно»): было три этажа и 18 px отступа сверху и снизу.
   Пунктир остаётся — он и говорит, что сюда можно бросить файл; вторая строка
   подсказки уехала в `title` самой зоны. Бросать по-прежнему можно на ВСЁ
   окно, не только сюда. */
.os-drop {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 7px 12px;
  border: 1px dashed var(--os-line);
  border-radius: var(--os-radius);
  transition: border-color .15s ease, background .15s ease;
}

.os-drop.is-drop {
  border-color: var(--os-accent);
  background: color-mix(in srgb, var(--os-accent) 10%, transparent);
}

.os-drop__title {
  font-size: 12px;
  color: var(--os-fg2);
}

.os-files {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.os-files__empty {
  font-size: 11px;
  color: var(--os-fg2);
}

.os-file {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  padding: 4px 8px;
  background: var(--os-ctl);
  border-radius: 10px;
}

.os-file__name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12px;
}

.os-file__src {
  flex: 0 0 auto;
  font-size: 11px;
  color: var(--os-fg2);
}

/* Красная строка расхождения сумм (решение 27 ТЗ): предупреждаем, но
   пропускаем — второе нажатие подтверждает. */
.os-warn {
  padding: 6px 10px;
  font-size: 12px;
  color: var(--os-bad);
  background: color-mix(in srgb, var(--os-bad) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--os-bad) 35%, transparent);
  border-radius: var(--os-radius);
}

.os-say {
  flex: 1 1 auto;
  font-size: 11px;
  color: var(--os-fg2);
  min-height: 14px;
}

/* ---------- состояние оплаченной и лента истории ---------- */

.os-state {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.os-feed {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.os-feed__say {
  font-size: 11px;
  color: var(--os-fg2);
}

.os-feed__row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
  font-size: 12px;
}

.os-feed__at {
  flex: 0 0 auto;
  color: var(--os-fg2);
  font-variant-numeric: tabular-nums;
}

.os-feed__what {
  flex: 1 1 160px;
  min-width: 0;
}

.os-feed__who {
  flex: 0 0 auto;
  color: var(--os-fg2);
}

/* Ссылка на сообщение бота в чате отчёта (владелец 14.09.2026): стоит и в
   строке ленты, и рядом с чипом доставки — правило одно на оба места. */
.os-chatlink {
  flex: 0 0 auto;
  font-size: 11px;
  color: var(--os-accent);
  text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, var(--os-accent) 40%, transparent);
  white-space: nowrap;
}

.os-chatlink:hover {
  border-bottom-color: var(--os-accent);
}

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

.os-note {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 8px;
  width: 100%;
  min-width: 0;
}

.os-note__text {
  flex: 1 1 200px;
  min-width: 0;
  padding: 6px 8px;
  font: inherit;
  font-size: 12px;
  color: var(--os-fg);
  background: var(--os-ctl);
  border: 1px solid var(--os-line);
  border-radius: 10px;
  resize: vertical;
}

.os-note__acts {
  display: flex;
  flex: 0 0 auto;
  gap: 6px;
}

/* ============================================================
   ВСТРАИВАНИЕ В РАЗДЕЛ BYBIT (слово владельца 14.09.2026)

   Виджет стоит рядом с ордерами, а КАК именно — решает макет раздела: классика
   (виджет в колонке «Покупка», включается чипом), половинчатый (полоса под
   обеими колонками) и три блока (третья колонка). Сетку страницы под эти
   макеты держит `css/pages/bybit.css`; здесь — сам слот, чипы шапки и окно
   выбора.

   Единственное место файла, где упоминаются ЧУЖИЕ классы, и упоминаются они
   ровно затем, чтобы чип «Остатки» мог спрятать родные блоки колонки. Свои
   классы здесь по-прежнему только `os-*`.

   ПОЧЕМУ `display: none`, а не `visibility` (ловушка 3 проекта). Ловушка про
   ГРИД-ребёнка: у него `display:none` убирает бокс из сетки и сдвигает
   авторасстановку соседей по колонкам. Здесь прячутся дети `.by-ords__col`, а
   она — ФЛЕКС-колонка (`display:flex; flex-direction:column`), и грид-детей
   (`.by-ords`, `.by-splitter`, `.by-ads` внутри `.by-work`) правила не трогают
   вовсе. `visibility: hidden` тут был бы неверен по смыслу: лента ордеров
   держит `flex: 1` и, оставшись в потоке, съела бы всю высоту — «Остаткам» не
   досталось бы ни пикселя.
   ============================================================ */

.os-slot {
  display: flex;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
}

/* Классика: слот занимает колонку под шапкой. Своей рамки и фона не берёт —
   он внутри панели колонки. */
.os-slot--col {
  flex: 1 1 auto;
  padding: 0 8px 8px;
}

/* Колонка показывает ордера — слота нет вовсе (виджет при этом жив: поток и
   счётчик чипа не прерываются). */
.os-mode--bybit .os-slot { display: none; }

/* Колонка показывает остатки — уходят её родные блоки. */
.os-mode--ostatki .by-ords__tabs,
.os-mode--ostatki .by-ordFilters,
.os-mode--ostatki .by-ords__list { display: none; }

/* ---------- чипы в шапке колонки ---------- */

/* Полоса стоит на общих классах колонки (`by-ordSeg`/`by-segBtn`) — так она
   неотличима от соседних сегментов раздела. Своё здесь: выравнивание в шапке
   (она на baseline, а у полосы своя середина), числа и подсветка новых. */
.os-chips {
  align-self: center;
}

/* Тач-высота `button` из mobile.css (40px) раздула бы чипы: правило адресное и
   ВНЕ media-запроса — специфичность 0,1,0 выигрывает при любом порядке файлов
   (ловушка 5 проекта). */
.os-chip {
  min-height: 0;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.os-chip__n {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

.os-chip__n:empty { display: none; }

/* Есть новые расписки — чип зовёт. Спрятанный виджет слепым пятном быть не
   должен. */
.os-chip--os.is-fresh { color: var(--os-accent); }
.os-chip--os.is-fresh .os-chip__n { color: var(--os-accent); }

.os-chip--gear {
  font-size: 12px;
  line-height: 1;
  padding: 3px 6px;
}

/* В половинчатом макете и в трёх блоках переключать нечего: чипы остаются
   счётчиками, и вид у них не «кнопка». */
.os-chips--info .os-chip:not(.os-chip--gear) { cursor: default; }

/* ---------- окно выбора макета ---------- */

.os-lay {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: min(420px, 100%);
  padding: 14px;
  /* Окну поверх страницы нужен НЕПРОЗРАЧНЫЙ фон (правило проекта). */
  background: var(--os-panel);
  border: 1px solid var(--os-line);
  border-radius: 16px;
  box-shadow: var(--os-shadow);
}

.os-lay__head {
  display: flex;
  align-items: center;
  gap: 10px;
}

.os-lay__title {
  font-size: 14px;
  font-weight: 700;
}

.os-lay__x {
  margin-left: auto;
  min-height: 0;
  width: 24px;
  height: 24px;
  padding: 0;
  font: inherit;
  font-size: 15px;
  line-height: 1;
  color: var(--os-fg2);
  background: var(--os-ctl);
  border: 1px solid var(--os-line);
  border-radius: 8px;
  cursor: pointer;
}

.os-lay__x:hover { background: var(--os-hov); color: var(--os-fg); }

.os-lay__opts {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.os-lay__opt {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  background: var(--os-ctl);
  border: 1px solid var(--os-line);
  border-radius: 12px;
  cursor: pointer;
}

.os-lay__opt:hover { background: var(--os-hov); }
.os-lay__opt.is-active { border-color: var(--os-accent); }

.os-lay__r { flex: 0 0 auto; }

/* Схема макета — рисунком из трёх прямоугольников: словами «половинчатый»
   объяснять дольше, чем показать. */
.os-lay__pic {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  width: 38px;
  height: 26px;
}

.os-lay__pic > i {
  background: var(--os-fg2);
  border-radius: 2px;
  opacity: .55;
}

.os-lay__pic--classic > i { width: calc(50% - 1px); height: 100%; }
.os-lay__pic--classic > i:nth-child(3) { display: none; }

.os-lay__pic--split > i:nth-child(1),
.os-lay__pic--split > i:nth-child(2) { width: calc(50% - 1px); height: calc(60% - 1px); }
.os-lay__pic--split > i:nth-child(3) { width: 100%; height: 40%; opacity: .8; }

.os-lay__pic--three > i { width: calc(33.333% - 2px); height: 100%; }
.os-lay__pic--three > i:nth-child(3) { opacity: .8; }

.os-lay__text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.os-lay__t { font-size: 12.5px; }
.os-lay__d { font-size: 11px; color: var(--os-fg2); }

/* ============================================================
   УЗКОЕ ОКНО (контейнер `oswin` — само плавающее окно)

   Окно шириной 640 px, а на телефоне — во весь экран: уже 470 px его делает
   узкий экран. Мерится ОКНО, а не экран (контейнерный запрос): одно и то же
   правило работает и в плавающем окне, и во весь экран. Ни одна строка наружу
   не выходит: длинные значения переносятся, поля встают этажами.
   ============================================================ */

/* Длинные значения переносим, а не выпускаем за край окна. */
.os-float .os-kv__v,
.os-float .os-feed__what,
.os-float .os-file__name {
  overflow-wrap: anywhere;
}

@container oswin (max-width: 470px) {
  /* Поле номера и «закрепить» в одну строку не помещаются — ставим этажами. */
  .os-pin {
    flex-direction: column;
    align-items: stretch;
  }

  /* Узкое комбо разложено НЕ ЗДЕСЬ, а рядом со своим правилом ниже: этот
     запрос стоит в файле ВЫШЕ `.os-combo`, а контейнерный запрос специфичности
     не добавляет — правило отсюда проиграло бы порядком и не сделало ничего. */

  .os-pin__input {
    flex: 1 1 auto;
  }

  .os-float .os-pin .os-btn {
    align-self: stretch;
  }

  .os-kv__k {
    width: 100%;
  }

  .os-win__sum {
    font-size: 16px;
  }

  /* Подвал узкого окна: действие во всю строку читается как кнопка, а не как
     обрубок. */
  .os-win__foot {
    align-items: stretch;
  }
}

/* ============================================================
   ВЫБОР ЖИВОГО ОРДЕРА BYBIT — комбо и раскрывающийся список

   Владелец 14.09.2026: «предлагаю разработать механизм, чтобы можно было при
   нажатии на окно ордер BYBIT выбрать нужный активный ордер для закрепления
   (обязательно проработай раскрывающийся список чтобы он соответствовал
   дизайну нашего сайта …)». Вид взят у портального `customSelect`
   (`.hc-selectMenu` в `css/base.css`): та же подложка `--page-bg-2`, то же
   скругление 14/12 px, та же тень и та же подсветка активного пункта. Сам
   виджет не подключается — он работает поверх `<select>` и не умеет ни поиска,
   ни произвольного номера, а поле здесь обязано оставаться обычным вводом:
   закрепить можно и номер чужой команды, которого в списке нет.

   СПИСОК ЖИВЁТ В `body` и стоит `position: fixed` по координатам поля (их
   считает `placeCombo` в `window.js`). Внутри виджета его резало бы: тело
   инлайнового окна прокручивается, у колонки раздела стоит `zoom`, а у
   оболочки `.content` — `transform`, и `fixed` внутри такого предка считается
   от него и обрезается его прокруткой.
   ============================================================ */

.os-combo {
  position: relative;
  display: flex;
  align-items: center;
  flex: 1 1 180px;
  min-width: 0;
}

/* В УЗКОМ БЛОКЕ `.os-pin` разложен КОЛОНКОЙ — и `flex-basis` комбо перестаёт
   быть шириной, становясь ВЫСОТОЙ: поле в 30 px занимало 180 px, а зона броска
   чека уезжала под нижний край окна (замер Codex в браузере 14.09.2026, окно
   360×620: зона начиналась на y=712 при границе окна y=683). Правило для
   `.os-pin__input` не спасает — поле лежит ВНУТРИ комбо.

   СТОИТ ИМЕННО ЗДЕСЬ, а не в общем узком запросе выше: контейнерный запрос
   специфичности не добавляет, и одинаково специфичные правила решает ПОРЯДОК —
   отсюда оно перебивает `flex: 1 1 180px`, а сверху файла не перебивало бы
   ничего (проверено в браузере: комбо оставалось 180 px). */
@container oswin (max-width: 470px) {
  .os-combo {
    flex: 0 0 auto;
    width: 100%;
  }
}

/* ШИРИНА ПОЛЯ НОМЕРА (владелец 20.09.2026: «строка ордера тоже [широкая]»):
   номер Bybit — девятнадцать цифр, а поле тянулось на всю ширину окна и
   обещало больше, чем в него когда-либо впишут.

   Правило стоит НА КОМБО, а не на поле — ровно по той причине, что описана
   абзацем выше: флекс-элементом внутри `.os-pin` является КОМБО. Первая
   попытка 20.09.2026 задала ширину самому полю (`.os-pin__input`) и не
   сделала НИЧЕГО, да и `.os-combo__input` ниже по файлу перебил бы её
   порядком. Ловушка описана в этом файле дважды — и оба раза в неё наступили
   (находка ревью 20.09.2026).

   Само правило живёт в ЕДИНСТВЕННОМ запросе «от ширины» (`min-width: 520px`,
   рядом с сеткой сведений): второй такой запрос запрещён сторожем — он
   стережёт, чтобы блоки окна не встали рядом, как было до 19.09.2026. */
.os-pin > .os-combo {
  min-width: 0;
}

.os-combo__input {
  flex: 1 1 auto;
  min-width: 0;
  padding-right: 30px;
}

/* Стрелка — своя, вместо системной стрелки селекта. */
.os-combo__caret {
  position: absolute;
  right: 6px;
  /* Явно по центру: у абсолютного ребёнка флекса вертикальное «статическое»
     место берётся из выравнивания контейнера, и полагаться на это незачем. */
  top: 50%;
  transform: translateY(-50%);
  min-height: 0;
  width: 20px;
  height: 20px;
  padding: 0;
  font: inherit;
  font-size: 11px;
  line-height: 1;
  color: var(--os-fg2);
  background: none;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
}

.os-combo__caret:hover {
  color: var(--os-fg);
  background: var(--os-hov);
}

.os-pop {
  position: fixed;
  z-index: 10006;
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-width: calc(100vw - 12px);
  padding: 8px;
  color: var(--os-fg);
  font-size: 12px;
  background: var(--os-panel);
  border: 1px solid var(--os-line);
  border-radius: 14px;
  box-shadow: var(--os-shadow);
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
}

.os-pop__head {
  padding: 0 4px 2px;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--os-fg2);
  text-transform: uppercase;
  letter-spacing: .04em;
}

.os-pop__say {
  padding: 8px 10px;
  color: var(--os-fg2);
}

.os-pop__say--bad {
  color: var(--os-bad);
}

.os-pop__list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

/* Пункт — как `.hc-selectOpt`: те же отступы, то же скругление, та же
   подсветка. Размер при наведении НЕ меняется (ловушка 4 портала: в
   прокручиваемом списке это даёт самоподдерживающийся каскад). */
.os-pop__opt {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 8px;
  min-width: 0;
  padding: 8px 10px;
  border: 1px solid transparent;
  border-radius: 12px;
  cursor: pointer;
  user-select: none;
}

.os-pop__opt:hover {
  background: color-mix(in srgb, var(--os-fg) 6%, transparent);
}

.os-pop__opt.is-active {
  background: color-mix(in srgb, var(--os-accent) 18%, transparent);
  border-color: color-mix(in srgb, var(--os-accent) 28%, transparent);
}

/* Заголовок группы: «на сумму остатка · N» и «остальные · M» (владелец
   15.09.2026). У второго — разделительная черта: ею и отделены группы. */
.os-pop__group {
  padding: 4px 10px 2px;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--os-fg2);
  text-transform: uppercase;
  letter-spacing: .04em;
}

.os-pop__group.is-split {
  margin-top: 4px;
  padding-top: 8px;
  border-top: 1px solid var(--os-line);
}

/* Занятый ордер: он уже закреплён за ДРУГОЙ распиской, и нажатие по нему
   ничего не закрепляет — только объясняет (владелец 15.09.2026: «слегка с
   красным фоном»). Подложка именно слегка: строка обязана остаться читаемой,
   а не стать тревогой. */
.os-pop__opt.is-taken {
  background: color-mix(in srgb, var(--os-bad) 11%, transparent);
}

.os-pop__opt.is-taken:hover {
  background: color-mix(in srgb, var(--os-bad) 16%, transparent);
}

.os-pop__taken {
  padding: 1px 6px;
  font-size: 10.5px;
  white-space: nowrap;
  color: var(--os-bad);
  background: color-mix(in srgb, var(--os-bad) 14%, transparent);
  border-radius: 999px;
}

/* Статус ордера биржи словом: при одинаковых суммах различает строки
   (владелец 15.09.2026). «Ждёт отпуска» — то, что делаем мы, и его выделяем. */
.os-pop__st {
  padding: 1px 6px;
  font-size: 10.5px;
  white-space: nowrap;
  color: var(--os-fg2);
  background: var(--os-ctl);
  border-radius: 999px;
}

.os-pop__st[data-bst="20"] {
  color: var(--os-amber);
}

.os-pop__num {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

.os-pop__side {
  padding: 1px 6px;
  font-size: 10.5px;
  color: var(--os-fg2);
  background: var(--os-ctl);
  border-radius: 999px;
}

/* Продажа — то, чем платят остаток: её и подсвечиваем. */
.os-pop__side[data-side="sell"] {
  color: var(--os-accent);
}

.os-pop__sum {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.os-pop__usdt {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--os-fg2);
}

.os-pop__acc,
.os-pop__cp {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--os-fg2);
}

.os-pop__cp {
  flex: 1 1 90px;
}

.os-pop__at {
  margin-left: auto;
  font-variant-numeric: tabular-nums;
  color: var(--os-fg2);
}

/* ============================================================
   ВНЕШНИЕ ЗАЯВКИ ИЗ TELEGRAM (фаза 2, 18.09.2026)

   `docs/ТЗ_ВНЕШНИЕ_ЗАЯВКИ_TG.md` §5.5: сегмент источника «все / свои /
   внешние» со счётчиком новых внешних (E21, только число), строка внешней
   заявки (автор, их номер, «похоже на дубль», «изменено», «отклонить»), в
   окне — блок заявки с исходным текстом, отложенная правка (E7), отказ с
   причиной из пяти; в «Завершённых» — сводка плитками за период, авторы и
   выгрузка XLSX.

   Блок стоит ДО первого media-запроса файла: каждой новой кнопке здесь
   объявлен `min-height: 0`, и специфичность, а не порядок, отбивает тач-высоту
   `mobile.css` (ловушка 5). Движения нет вовсе — только переходы наведения.
   ============================================================ */

/* Сегмент источника: выбранная кнопка — по атрибуту корня, как у отбора. */
.os[data-source="all"] .os-seg--source > button[data-source-set="all"],
.os[data-source="echo"] .os-seg--source > button[data-source-set="echo"],
.os[data-source="external"] .os-seg--source > button[data-source-set="external"] {
  color: var(--os-fg);
  background: var(--os-panel);
}

/* Есть новые внешние заявки — число на чипе зовёт акцентом. Только число:
   звука и вспышки нет (E21, правило 19.08.2026). */
.os-seg--source > button.is-fresh .os-seg__n {
  color: var(--os-accent);
  font-weight: 700;
}

/* Отказ по внешней заявке — своё слово «отказ» и свой цвет; OFF своих
   остатков (`data-st="cancelled"`) остаётся прежним. */
.os-ordStatus[data-st="declined"] {
  color: var(--os-bad);
  background: color-mix(in srgb, var(--os-bad) 14%, transparent);
}

/* «Отклонить» — не главная кнопка и не тревога: красные слова на обычной
   подложке, заливка — только под курсором. */
.os-btn--bad {
  color: var(--os-bad);
}

.os-btn--bad:hover:not(:disabled) {
  background: color-mix(in srgb, var(--os-bad) 14%, transparent);
}

/* «Просят отмену» — не ошибка и не предупреждение о нашей работе: их сторона
   передумала. Красным (`--os-bad`), потому что читать это надо ДО оплаты:
   расписку отзыв не гасит, решает человек (владелец 20.09.2026). */
.os-chip[data-chip="ask"] {
  color: var(--os-bad);
  background: color-mix(in srgb, var(--os-bad) 14%, transparent);
}

/* «Похоже на дубль» и «изменено» — предупреждения, а не ошибки: тёплые. */
.os-chip[data-chip="dup"],
.os-chip[data-chip="edit"] {
  color: var(--os-amber);
  background: color-mix(in srgb, var(--os-amber) 16%, transparent);
}

/* Поздняя правка — только пометка, решать нечего. */
.os-chip[data-chip="edit"][data-late="1"] {
  color: var(--os-fg2);
  background: var(--os-ctl);
}

/* Вопрос после 409 DELIVERY_UNCERTAIN: «Проверьте группу: чека там нет?».
   В строке списка — своей полосой под основной линией: в колонке действий
   он сжимал бы сумму и реквизит. */
.os-row__ask {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 6px 8px;
  min-width: 0;
  padding: 6px 10px 8px;
  border-top: 1px dashed color-mix(in srgb, var(--os-amber) 35%, var(--os-line));
}

.os-ask {
  min-width: 0;
  font-size: 11px;
  color: var(--os-amber);
  white-space: normal;
}

.os-row__ask .os-ask {
  flex: 1 1 160px;
}

/* ---------- окно: блок заявки ---------- */

.os-ext {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
  padding-top: 8px;
}

/* Исходный текст заявки — моноширинно и с переносами строк: шаблон из
   четырёх строк сверяют глазами построчно. Длинное — переносится, очень
   длинное — прокручивается внутри, окно не растёт без меры. */
/* Текст заявки НЕ во всю ширину (владелец 20.09.2026: «сообщение заявки вообще
   широкое сейчас»): четыре коротких строки — номер, реквизит, банк, сумма —
   растянутые на 600 px читаются хуже, чем прижатые к содержимому.

   Держит это `align-self`, а НЕ `display: inline-block`: `<pre>` лежит внутри
   `.os-ext` (`display: flex; flex-direction: column`), а флекс-элемент
   блокифицируется и при `align-items: normal` растягивается на всю поперечную
   ось — первая попытка 20.09.2026 не сделала ничего (находка ревью того же
   дня). `max-width` держит текст в окне, когда строка длинная. */
.os-ext__text {
  align-self: flex-start;
  max-width: 100%;
  margin: 0;
  padding: 8px 10px;
  max-height: 220px;
  overflow: auto;
  font-family: ui-monospace, "JetBrains Mono", Consolas, "Courier New", monospace;
  font-size: 12px;
  line-height: 1.45;
  color: var(--os-fg);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  background: var(--os-ctl);
  border-radius: 10px;
}

/* СКРИНШОТ к отказу (владелец 20.09.2026) — ТА ЖЕ однострочная зона `.os-drop`,
   что и у чека: бросок принимает всё окно, разбор идёт по режиму. Выглядит
   спокойно, потому что скриншот необязателен. Файл уходит чужой команде, вид и
   размер проверяет сервер по самим байтам. */
.os-dec__pick {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  font-size: 12px;
  color: var(--os-fg2);
  cursor: pointer;
}

.os-dec__shot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  min-width: 0;
  font-size: 12px;
}

.os-dec__shotName {
  flex: 1 1 140px;
  min-width: 0;
  color: var(--os-fg);
  overflow-wrap: anywhere;
}

/* Просьба об отмене из группы — красной полосой ПЕРВЫМ блоком тела: её
   читают до того, как платить (20.09.2026). Текст чужой — только через `esc`. */
.os-ext__ask {
  grid-column: 1 / -1;
  padding: 6px 10px;
  font-size: 12px;
  color: var(--os-bad);
  background: color-mix(in srgb, var(--os-bad) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--os-bad) 35%, transparent);
  border-radius: var(--os-radius);
}

.os-ext__askText {
  display: block;
  margin-top: 2px;
  color: var(--os-fg);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.os-ext__dup {
  padding: 6px 10px;
  font-size: 12px;
  color: var(--os-amber);
  background: color-mix(in srgb, var(--os-amber) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--os-amber) 35%, transparent);
  border-radius: var(--os-radius);
}

.os-ext__why,
.os-hrow__why {
  color: var(--os-bad);
}

/* ---------- окно: отложенная правка (E7) ---------- */

.os-edit {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
  padding: 10px;
  background: color-mix(in srgb, var(--os-amber) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--os-amber) 35%, transparent);
  border-radius: var(--os-radius);
}

.os-edit[data-late="1"] {
  background: var(--os-ctl);
  border-color: var(--os-line);
}

.os-edit__say {
  font-size: 12px;
}

.os-edit__errs {
  font-size: 12px;
  color: var(--os-bad);
}

.os-edit__acts {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px;
}

/* ---------- окно: отказ с причиной ---------- */

.os-dec {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
  min-width: 0;
}

/* Строки панели отказа — той же формы, что ордер и чек: подпись слева,
   содержимое справа. Своей линии сверху у них нет: панель и так отбита от
   окна одной линией секции. */
.os-dec__row {
  padding-top: 0;
  border-top: 0;
}

/* Предпросмотр и действия идут ПОД строками, во всю ширину. */
.os-dec__preview,
.os-dec__acts {
  width: 100%;
}

.os-dec__say,
.os-dec__preview {
  font-size: 12px;
  color: var(--os-fg2);
  overflow-wrap: anywhere;
}

.os-dec__reasons {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  min-width: 0;
}

/* Причина — КНОПКОЙ, а не пунктом <select> (ловушки 1 и 6). Выбранная —
   красной обводкой: это слово уйдёт в их группу. */
.os-dec__r {
  min-height: 0;
  padding: 4px 10px;
  font: inherit;
  font-size: 12px;
  color: var(--os-fg);
  background: var(--os-ctl);
  border: 1px solid var(--os-line);
  border-radius: 999px;
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}

.os-dec__r:hover:not(:disabled) {
  background: var(--os-hov);
}

.os-dec__r[aria-checked="true"] {
  color: var(--os-bad);
  background: color-mix(in srgb, var(--os-bad) 12%, transparent);
  border-color: color-mix(in srgb, var(--os-bad) 55%, var(--os-line));
}

.os-dec__r:disabled {
  opacity: .55;
  cursor: default;
}

.os-dec__acts {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px;
}

/* ---------- «Завершённые»: сводка внешних заявок ---------- */

.os-hext {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}

.os-hext__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.os-seg--period > button[aria-pressed="true"] {
  color: var(--os-fg);
  background: var(--os-panel);
}

.os-hext__label {
  font-size: 11px;
  color: var(--os-fg2);
  font-variant-numeric: tabular-nums;
}

.os-hext__xlsx {
  margin-left: auto;
}

/* Авторы — чипами-кнопками (нативного <select> в виджете нет). Имя задаёт
   их сторона либо наш админ — обрезается, а не раздвигает строку. */
.os-hext__who-list {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  min-width: 0;
}

.os-hext__who {
  min-height: 0;
  max-width: 220px;
  padding: 3px 10px;
  font: inherit;
  font-size: 12px;
  color: var(--os-fg2);
  background: var(--os-ctl);
  border: 1px solid transparent;
  border-radius: 999px;
  cursor: pointer;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}

.os-hext__who:hover {
  color: var(--os-fg);
  background: var(--os-hov);
}

.os-hext__who[aria-pressed="true"] {
  color: var(--os-fg);
  background: color-mix(in srgb, var(--os-accent) 12%, transparent);
  border-color: color-mix(in srgb, var(--os-accent) 45%, var(--os-line));
}

.os-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(120px, 100%), 1fr));
  gap: 8px;
  min-width: 0;
}

.os-tile {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding: 8px 12px;
  background: var(--os-panel);
  border: 1px solid var(--os-line);
  border-radius: var(--os-radius);
}

.os-tile__k,
.os-tile__sub {
  font-size: 11px;
  color: var(--os-fg2);
}

.os-tile__v {
  font-size: 17px;
  font-weight: 700;
}

.os-tile__v,
.os-tile__sub {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.os-tiles__say {
  grid-column: 1 / -1;
  font-size: 12px;
  color: var(--os-fg2);
}

.os-tiles__say[data-bad="1"] {
  color: var(--os-bad);
}

/* ---------- узко ---------- */

@media (max-width: 720px) {
  .os-head {
    gap: 6px;
  }

  .os-link {
    margin-left: 0;
    width: 100%;
  }

  .os-kv__k {
    width: 100%;
  }
}

/* Компактная строка истории на ленте поуже: курс уходит в подсказку ячейки
   USDT (`title` ставит `histRowHtml`), остальные колонки на месте. Запросы
   КОНТЕЙНЕРНЫЕ — мерить окно нельзя, виджет бывает уже него (колонка раздела
   Bybit). Порядок в файле — часть правила: узкий 560 стоит ПОСЛЕ 820 и
   перебивает его, специфичности контейнерный запрос не добавляет. */
@container (max-width: 820px) {
  .os-hrow {
    grid-template-columns: 84px auto 96px minmax(0, 1.2fr) minmax(0, 1fr) auto 84px;
    grid-template-areas: "st sum usdt req src num at";
  }

  .os-hrow__rate {
    display: none;
  }
}

/* На узкой ленте строка складывается в два этажа: восемь колонок в 400 px не
   влезают ни при какой обрезке. */
@container (max-width: 560px) {
  .os-hrow {
    grid-template-columns: auto minmax(0, 1fr) auto auto;
    grid-template-areas:
      "st req usdt sum"
      "src src num at";
    row-gap: 2px;
    padding: 7px 8px;
  }

  .os-hrow__sum {
    text-align: right;
  }

  .os-hrow__src {
    flex: 0 0 auto;
  }
}

/* На телефоне окна опускаются ниже шторки меню (z 200) и остаются выше нижней
   полосы (z 60) — то же, что делает у себя окно ордера (`.bw-win` уходит на
   150). Берём этажи ЧУТЬ НИЖЕ него, чтобы порядок «наши окна под карточкой
   ордера» сохранялся и здесь. Условие повторяет `mobile.css` дословно. */
@media (max-width: 860px) {
  .os-layer {
    z-index: 145;
    padding: 10px;
  }

  /* Окно расписки — во весь экран, переноса нет (`floatFrame.js` на узком
     экране жест не начинает и чистит свои `left/top`). `!important` — ради
     инлайна, который мог остаться от широкого экрана до первого пересчёта. */
  .os-float {
    z-index: 144;
    left: 0 !important;
    top: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    width: auto;
    max-height: none !important;
  }

  .os-float > .os-win {
    flex: 1 1 auto;
    border: 0;
    border-radius: 0;
  }

  .os-float .os-win__head {
    cursor: default;
  }

  /* Список ордеров едет за окном: он обязан остаться НАД ним и под шторкой. */
  .os-pop {
    z-index: 146;
  }
}

/* Окно расписки стоит у правого края страницы `/ostatki` — список уступает ему
   место справа и не прячется под ним (19.09.2026, `dockList` в `index.js`). На
   узком экране окно во весь экран, и сужать нечего. В конце файла: сторожа
   ловушки 5 ждут, что первый media-запрос стоит после правил `min-height: 0`. */
@media (min-width: 861px) {
  .os.is-docked > .os-pane {
    /* Отступ СНАРУЖИ панели: у неё `overflow: auto`, и полоса прокрутки
       должна остаться левее окна, а не под ним (ревью 19.09.2026). */
    margin-right: calc(min(640px, 100vw - 16px) + 16px);
  }
}
.os-live-search { display: flex; align-items: center; gap: 8px; flex: 1 1 280px; min-width: 0; }
.os-live-search .os-input { width: 100%; min-width: 0; }
.os-live-search[hidden] { display: none; }
