/* packages/ui/services.css
   Раскладка раздела «Сервисы» (план console-settings-catalog, Шаг 9) — только
   то, чего нет в существующих файлах: .panel/.page-head/.tabs/.tbl уже описаны
   в shell.css/table.css и переиспользуются как есть.

   Единственная содержательная причина существования этого файла: states.css
   рисует состояние (.state) АБСОЛЮТНО позиционированным (position: absolute;
   inset: 0) относительно ближайшего позиционированного предка, а сам по себе
   этот предок нигде в пакете position: relative не ставит (states.css:8 —
   единственное объявление position во всём packages/ui). services-list и
   services-card — оба узла, в которые может нарисовать состояние states.js
   (загрузка/пусто/ошибка/сервис недоступен) — обязаны сами быть
   position: relative, иначе состояние займёт (inset: 0) ближайшего чужого
   позиционированного предка вместо своей панели.

   Цвета — только var(--…) из 20 замороженных токенов packages/theme/tokens.css
   (tests/test_theme_contract.py), ни одного литерального hex.
*/

.services {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
}

.services .page-head {
  flex: none;
}

/* Список сервисов — СЕТКА ПЛАШЕК (ADR-0189 этой репы), а не дерево названий в
   колонке 260 px. На три сервиса колонка отъедала ширину у содержимого и не
   говорила о сервисе ничего, кроме имени. */
.services-list {
  position: relative; /* .state (states.css) позиционируется относительно этого узла */
  flex: 1;
  min-height: 240px;
  padding: 1.1rem;
  overflow-y: auto;
}

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  gap: .9rem;
}

/* Плашка сервиса. Форма — из макета: белая панель с рамкой, метка цвета у
   названия, описание, подвал с действием. Заливки цветом сервиса нет вовсе —
   она делала серый текст описания нечитаемым. */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: .7rem;
  text-align: left;
  width: 100%;
  cursor: pointer;
}

.card:hover {
  border-color: var(--border-2);
}

.card:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

.card .card-top {
  display: flex;
  align-items: center;
  gap: .55rem;
}

.card .card-top h3 {
  margin: 0;
  font-size: .96rem;
  font-weight: 650;
  color: var(--ink);
}

/* Описания на плашках больше нет (ADR-0191) — правило оставлено для плашек,
   которые его ещё несут (раздел «Дашборды»). */
.card p.desc {
  margin: 0;
  font-size: .845rem;
  line-height: 1.45;
  color: var(--ink-2);
}

/* Показатели плашки: число крупно, подпись под ним. Приезжают асинхронно и
   есть не у всех плашек, поэтому места под них заранее не резервируется —
   `gap` родителя расставит всё сам, когда и если они появятся. */
.card .meta {
  display: flex;
  flex-wrap: wrap;
  gap: 1.1rem;
}

.card .meta > div {
  display: flex;
  flex-direction: column;
  font-size: .78rem;
  color: var(--ink-3);
}

.card .meta b {
  font-size: 1.15rem;
  font-weight: 650;
  line-height: 1.25;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* `margin-top: auto` прижимает подвал к низу плашки: в сетке соседние плашки
   разной высоты, и без этого действие «Открыть» плясало бы по вертикали. */
.card .card-foot {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding-top: .6rem;
  border-top: 1px solid var(--border);
  margin-top: auto;
}

.card .btn.sm {
  margin-left: auto;
  padding: .25rem .55rem;
  font-size: .8rem;
}

.services-card {
  position: relative; /* .state (states.css) позиционируется относительно этого узла */
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 240px;
  overflow-y: auto;
}

/* Кнопка возврата стоит НАД заголовком экрана сервиса, отдельной строкой. */
.services-card .cfg-back {
  display: block;
  margin-bottom: .35rem;
}

/* Шапка экрана функции: кнопка возврата и название в одной строке, с теми же
   отступами, что у шапки сервиса. `flex: none` обязателен — иначе в колоночном
   флексе `.services-card` она делила бы с содержимым свободную высоту. */
.services-card .cfg-head {
  flex: none;
  align-items: baseline;
  padding: .8rem 1.1rem;
  margin-bottom: 0;
  border-bottom: 1px solid var(--border);
}

.services-card .cfg-host {
  flex: 1;
  min-height: 0;
  padding: 1.1rem;
  overflow-y: auto;
}

.svc-card {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

.svc-card h2 {
  margin: 0;
  font-size: 1.25rem;
  color: var(--ink);
}

.svc-card .svc-team {
  margin: .3rem 0 0;
  color: var(--ink-3);
  font-size: .82rem;
}

.svc-card .tab-pane {
  padding: 1.1rem;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}

/* Строка конфига — точка входа в форму (console-settings-form, Шаг 9).
   Кликабельность появилась вместе с потребителем шва data-config-id. */
.tbl tbody tr.row-link {
  cursor: pointer;
}
.tbl tbody tr.row-link:hover {
  background: var(--blue-wash);
}

/* --- Вкладка «История правок» карточки конфига ------------------------------
   (блок console-settings-scoring-audit, Шаг 8). Таблица — общая .tbl
   (table.css), состояния — общие .state (states.css); здесь только подписи и
   отступы, которых нет ни там, ни там.
*/

.audit-head {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: .7rem;
}

/* Подпись, объясняющая, ЧЕГО в журнале нет: имён изменённых полей Config
   Service не хранит вовсе. Пустая колонка без этой подписи читалась бы как
   «правок не было». */
.audit-hint {
  margin: 0;
  flex: 1;
  min-width: 16rem;
  font-size: .82rem;
  color: var(--ink-3);
}

.audit-filter {
  display: flex;
  align-items: center;
  gap: .45rem;
}

.audit-filter-label {
  font-size: .82rem;
  color: var(--ink-2);
}

.audit-actor {
  font: inherit;
  font-size: .86rem;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: .3rem .5rem;
  width: 9rem;
}

.audit-actor:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 1px;
}

.audit-list {
  position: relative; /* .state (states.css) позиционируется относительно этого узла */
  min-height: 4rem;
}

/* Запись без X-Actor — не «система», а пропущенный заголовок. Приглушённая
   подпись говорит именно это, вместо того чтобы выдумать автора. */
.audit-noactor {
  color: var(--ink-3);
  font-style: italic;
}

.audit-note {
  margin: .6rem 0 .4rem;
  font-size: .82rem;
  color: var(--ink-3);
}

/* Метка цвета сервиса у заголовка карточки. Раньше цвет уходил в
   `background-color` ВСЕЙ карточки и закрашивал её целиком вместе с описанием
   и таблицей настроек — серый текст на тёмной заливке переставал читаться.
   В эталоне (дашборды найма) сплошных заливок нет: панели белые, цветом
   помечают, а не заполняют. */
.card .card-top .svc-mark,
.svc-card h2 .svc-mark {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 3px;
  margin-right: .5rem;
  vertical-align: baseline;
  flex: none;
}

/* Части экрана функции (ADR-0191): своя форма и заимствованные группы стоят
   подряд, у каждой своя панель сохранения — это разные конфиги с разными
   `override_id`. Разделитель делает границу видимой, иначе две панели
   сохранения подряд читаются как одна сломанная. */
.cfg-part + .cfg-part {
  margin-top: 1.4rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--divider);
}

/* Позиционированный хозяин для плашек состояний СВОЕЙ части. `.state`
   объявлен `position: absolute; inset: 0`, и без этого правила ближайшим
   позиционированным предком оказывается `.services-card` — то есть весь экран
   функции. Спиннер после каждого сохранения центрировался бы по всей карточке,
   а плашка отказа (503, у неё нет кнопки «Повторить») ложилась бы прозрачным
   слоем поверх полосы вкладок и живой формы правил: кликать стало бы нечего, и
   выйти можно было бы только уходом со страницы.
   `min-height` — чтобы на время загрузки, когда своего содержимого у части
   нет, коробка не схлопнулась в ноль вместе с плашкой. */
.cfg-part {
  position: relative;
  min-height: 4rem;
}

/* Тело части — позиционированный хозяин для плашек состояний. `.state`
   объявлен `position: absolute; inset: 0`, и в безклассовом `div` ближайшим
   позиционированным предком оказался бы `.cfg-host`: спиннер и плашка ошибки
   одной секции легли бы поверх ВСЕГО экрана функции, закрыв рабочие формы
   конфига рядом. Высота — чтобы плашка не схлопнулась в ноль на пустом теле. */
.cfg-part-body {
  position: relative;
  min-height: 4rem;
}

.cfg-part-title {
  margin: 0 0 .7rem;
  font-size: .9rem;
  font-weight: 650;
  color: var(--ink);
}

/* Рычаг: кнопка вместо поля там, где человеку нужно действие, а не значение.
   Колоночный флекс с `align-items: flex-start` — иначе кнопка в два слова
   растянется во всю ширину (тот же дефект, что у «к дефолту» и у тумблера). */
.cfg-action {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: .4rem;
  margin-bottom: 1.2rem;
  padding: .8rem;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 6px;
}

/* Пояснение функции стоит МЕЖДУ шапкой и полосой вкладок, то есть прямым
   ребёнком `.services-card` — у которого своего горизонтального отступа нет:
   его держат `.cfg-head` и `.cfg-host` каждый у себя. Без этого правила абзац
   прижимался к левому краю панели, а заголовок над ним и настройки под ним
   стояли с отступом. Значение то же, что у соседей, — иначе текст «уезжает». */
.services-card .cfg-screen-summary {
  padding: .7rem 1.1rem 0;
  margin-bottom: 0;
}
