/* =======================================================================
   components.css — переиспользуемые UI-компоненты дизайн-системы «Преза».
   Зависит от tokens.css (цвета/spacing/radii/shadows). Без своих :root.
   Используется всеми app-экранами (admin/hub/login/users/log/help);
   viewer (index.html) подключает только tokens + эту базу кнопок/полей.
   =======================================================================
   Принципы:
   - все интерактивные элементы имеют :focus-visible (--focus-ring из tokens);
   - переходы через --t-base; никаких layout-thrash свойств в transition;
   - иконки — SVG-спрайт (.ic, см. icons.css).
*/

/* --- Базовый reset (без него любой <a> в bodyHtml падал бы в синий браузера) --- */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
a { color: inherit; text-decoration: none; }
img, svg, video { display: block; max-width: 100%; }
/* Атрибут hidden обязан побеждать display компонентов. Без этого правила
   .btn/.badge/.pill/.notice со своим inline-flex перебивают display:none из
   UA-стилей и элемент остаётся видимым (так админские ссылки в хабе показывались
   обычным пользователям). */
[hidden] { display: none !important; }
.link { color: var(--amber); }
.link:hover { text-decoration: underline; }

/* --- Фокус-обводка (a11y, только клавиатура) --- */
:focus { outline: none; }
:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  border-radius: var(--r-sm);
}
button:focus-visible, .btn:focus-visible, [role="button"]:focus-visible {
  box-shadow: var(--focus-ring);
}

/* --- Тело приложения (по умолчанию — app-режим: тёмный, без скролла) --- */
body {
  background: var(--bg);
  color: var(--text);
  font: var(--fs-md)/var(--lh-base) var(--font-sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
body.app {
  height: 100vh;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.mono { font-family: var(--font-mono); }
.serif { font-family: var(--font-serif); }
.dim { color: var(--dim); }
.grow { flex: 1; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* --- Сетки/утилиты --- */
.stack > * + * { margin-top: var(--sp-5); }
.cluster { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }
.wrap-bar { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }

/* =====================================================================
   Кнопки
   ===================================================================== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  font: inherit;
  font-weight: 500;
  line-height: 1.2;
  color: var(--text);
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: var(--sp-3) var(--sp-5);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--t-base), border-color var(--t-base), color var(--t-base), transform var(--t-fast);
  user-select: none;
}
.btn:hover { border-color: var(--amber); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .5; cursor: not-allowed; transform: none; }

.btn--primary {
  background: var(--amber);
  color: #201607;
  font-weight: 600;
  border-color: var(--amber);
}
.btn--primary:hover { background: #ffc66e; border-color: #ffc66e; }

.btn--ghost { background: transparent; }
.btn--ghost:hover { background: var(--panel-2); border-color: var(--line); }

.btn--subtle { background: transparent; border-color: transparent; }
.btn--subtle:hover { background: var(--panel-2); border-color: var(--line); }

.btn--danger { color: var(--text); }
.btn--danger:hover { color: var(--red); border-color: var(--red); background: transparent; }

.btn--success {
  background: var(--green);
  color: #04210f;
  font-weight: 600;
  border-color: var(--green);
}
.btn--success:hover { background: #44d088; border-color: #44d088; }

.btn--sm { padding: var(--sp-2) var(--sp-4); font-size: var(--fs-sm); }
.btn--lg { padding: var(--sp-4) var(--sp-6); font-size: var(--fs-lg); }
.btn--block { width: 100%; }

/* Только иконка (квадрат) */
.btn--icon {
  padding: 0;
  font-size: var(--fs-lg);
  width: calc(1em + 16px);
  height: calc(1em + 16px);
}

/* Ссылка-кнопка */
a.btn { text-decoration: none; display: inline-flex; }

/* =====================================================================
   Поля ввода
   ===================================================================== */
.field { display: block; margin-bottom: var(--sp-5); }
.field > .label,
.field > label {
  display: block;
  margin-bottom: var(--sp-2);
  color: var(--dim);
  font-size: var(--fs-sm);
}
.input, .select, .textarea,
input[type="text"], input[type="password"], input[type="email"],
input[type="search"], select, textarea {
  font: inherit;
  color: var(--text);
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: var(--sp-3) var(--sp-4);
  width: 100%;
  transition: border-color var(--t-base), box-shadow var(--t-base);
}
.input:hover, .select:hover, .textarea:hover { border-color: var(--amber-soft); }
.input:focus, .select:focus, .textarea:focus {
  outline: none;
  border-color: var(--amber);
  box-shadow: 0 0 0 3px rgba(255, 184, 77, .15);
}
.textarea {
  width: 100%;
  resize: vertical;
  min-height: 90px;
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
}
select {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238a8f9c' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--sp-4) center;
  padding-right: calc(var(--sp-4) * 2 + 12px);
  cursor: pointer;
}
input[type="checkbox"], input[type="radio"] { accent-color: var(--amber); }

/* Подпись-чекбокс */
.chk {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-sm);
  cursor: pointer;
  color: var(--dim);
}
.chk input { width: auto; }

/* =====================================================================
   Карточки
   ===================================================================== */
.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--sp-6);
  box-shadow: var(--shadow-card);
}
.card--hover:hover { border-color: var(--amber); }
.card__title { font-size: var(--fs-lg); line-height: var(--lh-tight); overflow-wrap: anywhere; }
.card__meta { color: var(--dim); font-size: var(--fs-sm); font-family: var(--font-mono); }

/* =====================================================================
   Бейджи
   ===================================================================== */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  font-size: var(--fs-xs);
  font-family: var(--font-mono);
  padding: 2px var(--sp-2);
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  color: var(--dim);
  white-space: nowrap;
}
.badge--amber { color: var(--amber); border-color: rgba(255,184,77,.35); }
.badge--green { color: var(--green); border-color: rgba(47,191,113,.35); }
.badge--red   { color: var(--red);   border-color: rgba(229,72,77,.35); }

/* Точка-индикатор (●) */
.dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }

/* =====================================================================
   Статус-пилюля (сохранено/грязно/ошибка)
   ===================================================================== */
.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-sm);
  color: var(--dim);
  padding: 3px var(--sp-3);
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
}
.pill--dirty { color: var(--amber); border-color: rgba(255,184,77,.35); }
.pill--ok    { color: var(--green); border-color: rgba(47,191,113,.35); }
.pill--err   { color: var(--red);   border-color: rgba(229,72,77,.35); }

/* =====================================================================
   Верхняя панель (topbar)
   ===================================================================== */
.topbar {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;             /* адаптив: перенос на узких экранах */
  min-height: 52px;
}
.topbar .brand {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-weight: 600;
  font-size: var(--fs-lg);
}
.topbar .brand .ic { color: var(--amber); font-size: 1.1em; }
.topbar .brand .sub { color: var(--dim); font-weight: 400; font-size: var(--fs-sm); }
.topbar .me { color: var(--dim); font-size: var(--fs-sm); font-family: var(--font-mono); }

/* =====================================================================
   Сегментный контрол (вкладки-переключатель)
   ===================================================================== */
.seg {
  display: inline-flex;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 3px;
  gap: 2px;
}
.seg__btn {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--dim);
  font: inherit;
  padding: var(--sp-2) var(--sp-4);
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background var(--t-base), color var(--t-base);
}
.seg__btn:hover { color: var(--text); }
.seg__btn[aria-pressed="true"],
.seg__btn.is-active {
  background: var(--panel);
  color: var(--text);
  box-shadow: var(--shadow-card);
}

/* =====================================================================
   Модальные окна
   (js/modal.js строит разметку; фон .modal__backdrop кликом закрывает)
   ===================================================================== */
.modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-5);
}
.modal[hidden] { display: none; }
.modal__backdrop {
  position: absolute;
  inset: 0;
  background: var(--backdrop);
  backdrop-filter: blur(2px);
  animation: modal-fade var(--t-base) ease;
}
.modal__dialog {
  position: relative;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-pop);
  width: min(92vw, 440px);
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: modal-pop var(--t-base) ease;
}
.modal__dialog--lg { width: min(92vw, 600px); }
.modal__header {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-5) var(--sp-6);
  border-bottom: 1px solid var(--line);
}
.modal__title { font-size: var(--fs-lg); flex: 1; }
.modal__close {
  appearance: none;
  background: transparent;
  border: 0;
  color: var(--dim);
  cursor: pointer;
  font-size: var(--fs-lg);
  padding: var(--sp-1);
  border-radius: var(--r-sm);
}
.modal__close:hover { color: var(--text); background: var(--panel-2); }
.modal__body { padding: var(--sp-6); overflow-y: auto; }
.modal__body p { margin: 0 0 var(--sp-4); }
.modal__body p:last-child { margin-bottom: 0; }
.modal__footer {
  display: flex;
  justify-content: flex-end;
  gap: var(--sp-3);
  padding: var(--sp-5) var(--sp-6);
  border-top: 1px solid var(--line);
  background: var(--bg);
}
/* пустой подвал не должен рисовать полосу — например, у пикера шаблонов,
   где загружать нечего. Правило идёт после основного, иначе будет перебито. */
.modal__footer:empty { display: none; }
@keyframes modal-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes modal-pop  { from { opacity: 0; transform: translateY(8px) scale(.98); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .modal__backdrop, .modal__dialog { animation: none; }
}

/* =====================================================================
   Тосты (короткие уведомления)
   ===================================================================== */
.toast-wrap {
  position: fixed;
  z-index: var(--z-toast);
  right: var(--sp-6);
  bottom: var(--sp-6);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  max-width: calc(100vw - var(--sp-8));
}
.toast {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  background: var(--panel);
  border: 1px solid var(--line);
  border-left: 3px solid var(--dim);
  border-radius: var(--r-md);
  padding: var(--sp-3) var(--sp-5);
  box-shadow: var(--shadow-drop);
  font-size: var(--fs-sm);
  animation: toast-in var(--t-base) ease;
}
.toast--ok    { border-left-color: var(--green); }
.toast--err   { border-left-color: var(--red); }
.toast--warn  { border-left-color: var(--amber); }
.toast .ic { font-size: var(--fs-lg); }
.toast--ok  .ic { color: var(--green); }
.toast--err .ic { color: var(--red); }
.toast--warn .ic { color: var(--amber); }
.toast.is-leaving { animation: toast-out var(--t-base) ease forwards; }
@keyframes toast-in  { from { opacity: 0; transform: translateX(16px); } to { opacity: 1; transform: none; } }
@keyframes toast-out { to   { opacity: 0; transform: translateX(16px); } }

/* =====================================================================
   Плашка-уведомление в потоке страницы (не всплывашка).
   Для разовых сообщений, требующих решения — например, предложение
   восстановить локальную резервную копию в редакторе.
   ===================================================================== */
.notice {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-5);
  background: var(--panel-2);
  border-bottom: 1px solid var(--line);
  border-left: 3px solid var(--amber);
  font-size: var(--fs-sm);
  flex-wrap: wrap;
}
.notice .ic { color: var(--amber); flex-shrink: 0; }
.notice__text { color: var(--text); }
.notice__text b { color: var(--amber); font-weight: 600; }
.notice .grow { flex: 1; }

/* =====================================================================
   Тултипы (подсказки к кнопкам-иконкам, см. js/tooltip.js)
   Рисуются одним элементом в <body> с position:fixed — иначе их обрезали бы
   скролл-контейнеры (.inspector, .slide-list, #hub) и overflow:hidden у body.
   ===================================================================== */
.tip {
  position: fixed;
  z-index: var(--z-tooltip);
  top: 0;
  left: 0;
  max-width: 260px;
  padding: var(--sp-2) var(--sp-3);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-drop);
  color: var(--text);
  font-size: var(--fs-sm);
  line-height: var(--lh-base);
  white-space: normal;
  pointer-events: none;   /* курсор не должен цепляться за подсказку */
  opacity: 0;
  transition: opacity var(--t-fast);
}
.tip.is-on { opacity: 1; }

/* стрелка-указатель; переворачивается вместе с подсказкой */
.tip::after {
  content: '';
  position: absolute;
  left: var(--tip-arrow, 50%);
  width: 7px;
  height: 7px;
  margin-left: -4px;
  background: var(--panel);
  border: 1px solid var(--line);
  transform: rotate(45deg);
}
.tip::after            { bottom: -5px; border-top: 0; border-left: 0; }
.tip.tip--below::after { bottom: auto; top: -5px; border: 1px solid var(--line); border-bottom: 0; border-right: 0; }

/* тач-устройства: подсказки по наведению не имеют смысла */
@media (hover: none) {
  .tip { display: none; }
}

/* =====================================================================
   Меню (dropdown)
   ===================================================================== */
.menu {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-drop);
  padding: var(--sp-1);
  min-width: 180px;
}
.menu__item {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-sm);
  color: var(--text);
  font-size: var(--fs-sm);
  cursor: pointer;
}
.menu__item:hover { background: var(--panel-2); }
.menu__item--danger:hover { color: var(--red); }

/* =====================================================================
   Таблицы (users/log)
   ===================================================================== */
.table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.table th, .table td {
  text-align: left;
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}
.table th {
  color: var(--dim);
  font-weight: 500;
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: .04em;
}
.table tr:hover td { background: var(--panel); }
.table .num { font-family: var(--font-mono); color: var(--dim); }

/* =====================================================================
   Подсказка/пустое состояние
   ===================================================================== */
.hint { color: var(--dim); font-size: var(--fs-sm); }
.empty-state {
  text-align: center;
  color: var(--dim);
  padding: var(--sp-9) var(--sp-6);
}
.empty-state .ic { font-size: 40px; color: var(--line); margin: 0 auto var(--sp-5); }
