:root { color-scheme: light dark; font-family: system-ui, sans-serif; }
/* генеричный .hidden: раньше был привязан только к .modal-overlay/.modal-field, и «скрытый»
   #job-panel на деле рендерился — просто был пуст и потому невидим, пока кнопка
   «копировать лог» его не проявила */
.hidden { display: none !important; }
/* safe-area-inset-* — iPhone-режим «веб-приложение» (standalone): не прятать контент под
   вырез/индикатор Home; на обычных экранах env() = 0 и остаются базовые отступы */
body {
  margin: 0;
  padding: 0 max(16px, env(safe-area-inset-right)) max(32px, env(safe-area-inset-bottom))
    max(16px, env(safe-area-inset-left));
}
header {
  display: flex; align-items: center; gap: 16px; border-bottom: 1px solid #8884;
  padding: max(14px, env(safe-area-inset-top)) 0 14px;
}
h1 { font-size: 20px; margin: 0; }
button { cursor: pointer; padding: 4px 10px; border: 1px solid #8886; border-radius: 6px; background: #8881; font-size: 13px; }
button:hover { background: #8883; }
button.warn { border-color: #c0532a; color: #c0532a; }
button.primary { border-color: #1a7f37; color: #1a7f37; font-weight: 600; }
.muted { opacity: .6; font-size: 12px; }
header { flex-wrap: wrap; }
/* .table-wrap — таблицы скроллятся горизонтально ВНУТРИ обёртки, а не распирают страницу:
   раньше 7 колонок клиентов с телефона растягивали body, и вправо уезжала вся страница
   (шапка, чипы здоровья — всё обрезалось) */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; margin-top: 14px; }
.table-wrap table { margin-top: 0; }
table { width: 100%; border-collapse: collapse; margin-top: 14px; }
th, td { text-align: left; padding: 8px 10px; border-bottom: 1px solid #8883; font-size: 14px; vertical-align: middle; }
th { white-space: nowrap; }
td.ok { color: #1a7f37; }
td.bad { color: #c0392b; }
#log { background: #8881; border: 1px solid #8883; border-radius: 6px; padding: 10px; max-height: 320px; overflow: auto; font-size: 12px; white-space: pre-wrap; }

button:disabled { opacity: .45; cursor: not-allowed; }
.busy-note { font-size: 12px; opacity: .8; white-space: nowrap; }

.job-panel { margin-top: 14px; }
.job-head { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
.job-head button { white-space: nowrap; }
.job-panel h3 { flex: 1; margin: 0; font-size: 15px; }
.job-panel h3.ok { color: #1a7f37; }
.job-panel h3.bad { color: #c0392b; }
#job-log { background: #8881; border: 1px solid #8883; border-radius: 6px; padding: 10px; max-height: 260px; overflow: auto; font-size: 12px; white-space: pre-wrap; }

.qr-img { display: block; margin: 0 auto 10px; width: min(256px, 70vw); background: #fff; padding: 8px; border-radius: 6px; image-rendering: pixelated; }
.qr-url { font-size: 11px; word-break: break-all; opacity: .75; margin: 0 0 8px; }
.qr-help { font-size: 12px; word-break: break-all; opacity: .85; margin: 0 0 12px; }
.modal-actions { flex-wrap: wrap; }

.health { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 14px; font-size: 13px; align-items: center; }
.layer-label { opacity: .55; font-size: 12px; }
.layer-note { margin-top: 14px; font-size: 12px; opacity: .6; }
.table-wrap + .layer-note, .layer-note + .table-wrap { margin-top: 6px; }
.chip { padding: 3px 9px; border: 1px solid #8885; border-radius: 999px; background: #8881; white-space: nowrap; }
.chip.ok { color: #1a7f37; border-color: #1a7f3766; }
.chip.bad { color: #c0392b; border-color: #c0392b66; }
.chip.blocked { color: #c0392b; border-color: #c0392b; font-weight: 600; }
.chip.warn { color: #c0532a; border-color: #c0532a66; }

.client-add { display: flex; gap: 8px; margin-top: 14px; }
.client-add input { flex: 1; box-sizing: border-box; padding: 7px 9px; border: 1px solid #8886; border-radius: 6px; background: #8881; color: inherit; font-size: 14px; }
.sparkline { display: block; opacity: .85; }

.modal-overlay { position: fixed; inset: 0; background: #0008; display: flex; align-items: center; justify-content: center; z-index: 10; }
.modal-overlay.hidden { display: none; }
.modal { background: Canvas; color: CanvasText; border: 1px solid #8886; border-radius: 8px; padding: 18px 20px; width: min(360px, 90vw); box-shadow: 0 8px 24px #0006; max-height: 85vh; overflow-y: auto; }
.modal h3 { margin: 0 0 6px; font-size: 16px; }
.modal p { margin: 0 0 14px; font-size: 13px; opacity: .75; }
.modal-field { display: block; font-size: 13px; margin-bottom: 14px; }
.modal-field.hidden { display: none; }
.modal-field span { display: block; margin-bottom: 4px; }
.modal-field input { width: 100%; box-sizing: border-box; padding: 7px 9px; border: 1px solid #8886; border-radius: 6px; background: #8881; color: inherit; font-size: 14px; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; }
.job-hist-row { cursor: pointer; }
.job-hist-row b.ok { color: #1a7f37; }
.job-hist-row b.bad { color: #c0392b; }
.job-hist-log { background: #8881; border: 1px solid #8883; border-radius: 6px; padding: 8px; max-height: 200px; overflow: auto; font-size: 11px; white-space: pre-wrap; margin: 6px 0 0; cursor: auto; }

/* Парк VPS — отдельный «экран» (скрывает main). */
#inventory-view { padding-top: max(14px, env(safe-area-inset-top)); }
.inv-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.inv-head h2 { flex: 1; margin: 0; font-size: 20px; }
.inv-hint { font-size: 13px; opacity: .7; margin: 8px 0 0; }
.inv-summary { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: baseline; margin-top: 10px; font-size: 14px; }
.cost-amounts { font-weight: 600; }
.cost-total { font-size: 16px; color: #1a7f37; flex-basis: 100%; }
.cost-breakdown { font-weight: 400; font-size: 13px; opacity: .8; flex-basis: 100%; }
.cost-hidden-note { display: none; } /* показывается только в режиме скрытия */
/* режим скрытия сумм: прячем сводку и колонку стоимости, показываем плейсхолдер */
.costs-hidden .cost-amounts, .costs-hidden .inv-summary .chip.warn { display: none; }
.costs-hidden .cost-hidden-note { display: inline; }
.costs-hidden .cost-cell { color: transparent; user-select: none; position: relative; }
.costs-hidden .cost-cell::after { content: "•••"; color: GrayText; position: absolute; left: 10px; }
.inv-row { cursor: pointer; }
.inv-row:hover td { background: #8881; }
#inv-search { box-sizing: border-box; width: 100%; margin-top: 12px; padding: 8px 10px; border: 1px solid #8886; border-radius: 6px; background: #8881; color: inherit; font-size: 14px; }
#inv-table th.sortable { cursor: pointer; user-select: none; white-space: nowrap; }
#inv-table th.sortable:hover { background: #8881; }
#inv-table th.sortable.sorted { color: #1a7f37; }
#inv-table th.sortable.sorted::after { content: attr(data-arrow); }
/* поле + кнопка в одной строке (локация «по IP») */
.field-with-btn { display: flex; gap: 6px; }
.field-with-btn input { flex: 1; min-width: 0; }
.field-with-btn button { white-space: nowrap; }
/* число + селектор единицы (характеристики) */
.field-with-unit { display: flex; gap: 6px; }
.field-with-unit input { flex: 1; min-width: 0; }
.field-with-unit select { flex: 0 0 auto; padding: 7px 6px; border: 1px solid #8886; border-radius: 6px; background: #8881; color: inherit; font-size: 14px; }
#inv-table td.warn { color: #c0532a; }
#inv-table td.bad { color: #c0392b; font-weight: 600; }

/* форма VPS — двухколоночная сетка, заметки на всю ширину */
.vps-modal { width: min(560px, 94vw); }
.vps-form { display: grid; grid-template-columns: 1fr 1fr; gap: 0 12px; }
.vps-form .modal-field { margin-bottom: 10px; }
.vps-form .vps-notes { grid-column: 1 / -1; }
.vps-form select, .vps-form textarea {
  width: 100%; box-sizing: border-box; padding: 7px 9px; border: 1px solid #8886;
  border-radius: 6px; background: #8881; color: inherit; font-size: 14px; font-family: inherit;
}
#vps-delete { margin-right: auto; } /* «удалить» слева, ок/отмена справа */
@media (max-width: 640px) { .vps-form { grid-template-columns: 1fr; } }

.login-wrap { min-height: 100vh; min-height: 100dvh; display: flex; align-items: center; justify-content: center; }
.login { display: flex; flex-direction: column; gap: 10px; width: min(320px, 90vw); }
.login h1 { font-size: 20px; margin: 0 0 4px; text-align: center; }
.login input { box-sizing: border-box; padding: 8px 10px; border: 1px solid #8886; border-radius: 6px; background: #8881; color: inherit; font-size: 14px; }
.login button { padding: 8px 10px; }
.login-error { margin: 0; font-size: 13px; color: #c0392b; text-align: center; }
.login-context { margin: 0 0 2px; font-size: 13px; opacity: .7; text-align: center; }
.login-context code { font-size: 12px; }
.login-token { display: flex; gap: 6px; }
.login-token input { flex: 1; min-width: 0; }
.login-token button { padding: 8px 10px; }

/* toast-уведомления: поверх всего, сверху; на телефоне — во всю ширину. Ошибка job'а
   (ms=0) висит до клика — критику нельзя пропустить. */
#toasts {
  position: fixed; z-index: 100;
  top: max(10px, env(safe-area-inset-top)); right: max(10px, env(safe-area-inset-right));
  left: max(10px, env(safe-area-inset-left));
  display: flex; flex-direction: column; gap: 8px; align-items: flex-end;
  pointer-events: none;
}
.toast {
  pointer-events: auto; cursor: pointer;
  max-width: min(440px, 100%); box-sizing: border-box;
  background: Canvas; color: CanvasText;
  border: 1px solid #8886; border-left: 4px solid #888a; border-radius: 8px;
  padding: 9px 12px; font-size: 13px; word-break: break-word;
  box-shadow: 0 6px 18px #0005; transition: opacity .4s;
}
.toast.ok { border-left-color: #1a7f37; }
.toast.bad { border-left-color: #c0392b; }
.toast.warn { border-left-color: #c0532a; }
.toast.fade { opacity: 0; }

/* узкие экраны (iPhone): плотнее отступы, кнопки не мельчим (пальцем попадать),
   длинные метки заняты переносом, а не распором строки */
@media (max-width: 640px) {
  body {
    padding-left: max(10px, env(safe-area-inset-left));
    padding-right: max(10px, env(safe-area-inset-right));
  }
  header { gap: 8px; }
  th, td { padding: 6px 6px; font-size: 13px; }
  button { padding: 6px 10px; }
  .busy-note { white-space: normal; }
  .health { font-size: 12px; }
  #toasts { align-items: stretch; }
  .toast { max-width: none; }
  .modal { padding: 14px 14px; }
}
