/* ==========================================================================
   Новый вид: приёмы страниц
   --------------------------------------------------------------------------
   Сборки из деталей дизайн-системы, которые повторяются от страницы к
   странице. Отдельно от components.css: компоненты сверены с Vuexy, а это
   наши раскладки (у Vuexy их нет или они в каждом экране свои).
   ========================================================================== */

/* Карточки стопкой с одинаковым шагом */
.stack { display: grid; gap: 1.5rem; }
.stack-sm { display: grid; gap: 1rem; }

/* Раздел с меню слева: настройки, карточка ученика, бот */
.side-layout { display: grid; gap: 1.5rem; align-items: start; }
@media (min-width: 992px) { .side-layout { grid-template-columns: 15.5rem minmax(0, 1fr); } }
.side-nav { position: sticky; top: calc(var(--navbar-height) + 2rem); }
.side-nav .nav-pills { gap: 0.125rem; }
.side-nav .nav-pills .nav-link { justify-content: flex-start; width: 100%; margin: 0; gap: 0.625rem; }
.side-nav .nav-pills .nav-link .ic,
.side-nav .nav-pills .nav-link .lms-icon { width: 1.25rem; height: 1.25rem; }
.side-cap { margin: 1.25rem 0 0.5rem; padding-inline: 1rem; color: var(--bs-secondary-color); font-size: 0.8125rem; letter-spacing: 0.4px; text-transform: uppercase; }
.side-cap:first-child { margin-top: 0; }
/* -------------------------------------- шапка страниц настроек липнет
 *
 * Замечание владельца 05.10: на длинной странице настройки («Витрина
 * и цвет») шапка уезжала вверх, и посреди страницы не было видно, какую
 * настройку правишь. Меню настроек слева при этом уже липло — и
 * оставалось ответом без вопроса.
 *
 * Узнаём страницу настроек по устройству, а не по списку адресов: шапка,
 * за которой идёт раскладка с меню настроек. Новая страница настроек
 * получает липкую шапку сама.
 *
 * Фон — отдельным слоем (::before), а не фоном самой шапки: у шапки
 * справа поле 9.5rem под значки панели (components.css), и содержимое,
 * проезжая под шапкой, было бы видно в этом поле рядом со значками.
 * Слой тянется вправо на ширину поля и закрывает его.
 *
 * Меню настроек встаёт под шапку на её настоящую высоту
 * (--settings-head, меряет ui.js): подзаголовок переносится по-разному,
 * и угаданное число однажды задвинуло бы верх меню под шапку.
 */
@media (min-width: 992px) {
  .app-content > .page-header:has(+ .side-layout > .settings-nav) {
    position: sticky;
    /* 0.5rem, а не 0: столько же шапка стоит от верха и в покое (поле
       кабинета), и прилипшая она не подскакивает. При top: 0 она уходила
       на 8 точек выше, и с 08.10, когда кнопки встали под значками
       панели, кнопка упиралась в аватарку ровно краем. */
    top: 0.5rem;
    /* ниже значков панели (1002), выше страницы */
    z-index: 1001;
    margin-top: -1.5rem;
    padding-top: 1.5rem;
    padding-bottom: 1rem;
    margin-bottom: 0.5rem;
  }
  .app-content > .page-header:has(+ .side-layout > .settings-nav)::before {
    content: "";
    position: absolute;
    /* и над шапкой полрема фона: прилипшая на 0.5rem, она иначе
       оставляла сверху щель, в которой проезжала страница */
    inset-block: -0.5rem 0;
    inset-inline: 0;
    z-index: -1;
    background: var(--bs-body-bg);
    transition: box-shadow var(--duration) var(--ease);
  }
  /* Черта под шапкой — только когда под неё уже что-то заехало, то есть
     страница прокручена: в покое она резала бы шапку от страницы. */
  .app-navbar.is-scrolled ~ .app-content > .page-header:has(+ .side-layout > .settings-nav)::before {
    box-shadow: 0 1px 0 var(--bs-border-color);
  }
  .app-content > .page-header:has(+ .side-layout > .settings-nav) + .side-layout > .settings-nav.side-nav {
    top: calc(var(--settings-head, 7rem) + 1.5rem);
    /* Своя прокрутка на низком экране: прилипшее меню обрезается окном.
       Полоса прокрутки спрятана, как у бокового меню (components.css):
       на 900 точках высоты меню вставало впритык, и полоса проступала
       от разницы в доли точки, хотя прокручивать было нечего. */
    max-height: calc(100vh - var(--settings-head, 7rem) - 2rem);
    overflow-y: auto;
    scrollbar-width: none;
  }
  .app-content > .page-header:has(+ .side-layout > .settings-nav) + .side-layout > .settings-nav.side-nav::-webkit-scrollbar { display: none; }
}
/* Значки панели висят над страницей справа только с 1200 точек; уже —
   панель идёт полосой во всю ширину, и места под значки у шапки нет. */
@media (min-width: 1200px) {
  /* Слой тянется вправо на поле под значки. До 08.10 тянулся с 992,
     и на 992–1199, где поля нет, вылезал за край: страница
     прокручивалась вбок на ширину поля. */
  .app-content > .page-header:has(+ .side-layout > .settings-nav)::before {
    inset-inline: 0 -9.5rem;
  }
  /* Шапка с кнопками с 08.10 идёт во всю ширину сама (components.css,
     «главная кнопка — в правом углу»), и слою не нужно тянуться за неё:
     вытянутый на 9.5rem вправо, он вылез бы за край страницы. Кроме
     страниц раздела (data-bare-header): там с вечера 08.10 кнопка слева
     в строке значков, поле под значки у шапки снова есть, и без слоя
     в нём проезжала прокрученная страница. */
  .app-content:not([data-bare-header]) > .page-header:has(+ .side-layout > .settings-nav):has(> .page-actions)::before {
    inset-inline: 0;
  }
  /* ПУСТАЯ липкая шапка (разделы без шапки, data-bare-header, с 08.10):
     заголовок спрятан, кнопок нет — и шапка сжималась до своих полей,
     8–48 точек. Значки панели кончаются на 64, и содержимое настройки
     вставало под них правым верхним углом (замечание владельца 09.10,
     «окно наезжает на панель с профилем»). Высота 3.5rem доводит низ
     шапки до 64, и содержимое начинается на 72 — там же, где на всех
     остальных разделах без шапки. */
  [data-bare-header] > .page-header:has(+ .side-layout > .settings-nav):not(:has(.page-actions > *)) {
    min-height: 3.5rem;
  }
}

@media (max-width: 991.98px) {
  /* без этого полоса пунктов растягивает сетку шире экрана */
  .side-layout { grid-template-columns: minmax(0, 1fr); }
  .side-nav { position: static; }
  .side-nav .nav-pills { flex-direction: row !important; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .side-nav .nav-pills .nav-link { width: auto; white-space: nowrap; }
  .side-nav .side-cap { display: none; }
}

/* Подпись и значение в две колонки */
.kv { display: grid; grid-template-columns: minmax(8rem, 12rem) minmax(0, 1fr); gap: 0.625rem 1rem; margin: 0; }
.kv dt { color: var(--bs-secondary-color); font-weight: 400; }
.kv dd { margin: 0; color: var(--bs-heading-color); }
@media (max-width: 575.98px) { .kv { grid-template-columns: minmax(0, 1fr); gap: 0.125rem; } .kv dd { margin-bottom: 0.5rem; } }

/* Строка фильтров над таблицей */
.filters { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; }
.filters .form-control, .filters .form-select { width: auto; min-width: 12rem; max-width: 100%; }
.filters .input-group { width: auto; flex: 1 1 16rem; max-width: 26rem; }
/* поле внутри группы тянется по группе, общее min-width его ломало */
.filters .input-group > .form-control,
.filters .input-group > .form-select { flex: 1 1 auto; width: 1%; min-width: 0; }

/* Плитки выбора (курсы, шаблоны, каналы) */
.tiles { display: grid; gap: 1.5rem; grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); }

/* Число с подписью в ряд (сводка над таблицей) */
.summary { display: grid; gap: 1.5rem; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }

/* Опасное действие внизу настроек */
.danger-zone .card-title { color: var(--bs-danger-text-emphasis); }

/* Липкая полоса сохранения внизу длинной формы */
.savebar {
  position: sticky;
  bottom: 1rem;
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 0.75rem;
  margin-top: 1.5rem;
  padding: 0.75rem 1rem;
  border-radius: var(--bs-border-radius);
  background: rgba(var(--paper-rgb), 0.9);
  box-shadow: var(--bs-box-shadow);
  -webkit-backdrop-filter: saturate(200%) blur(6px);
  backdrop-filter: saturate(200%) blur(6px);
}

/* Та же полоса без липкости и подложки: кнопка слева под формой, рядом
   строка автосохранения (ui2/js/autosave.js). Для форм, которые
   сохраняются сами, — кнопка там запасная и за прокруткой не ездит. */
.savebar-flow {
  position: static;
  justify-content: flex-start;
  padding: 0;
  background: none;
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
.savebar-status { color: var(--bs-secondary-color); font-size: 0.8125rem; }
.savebar-status.is-error { color: var(--bs-danger-text-emphasis); }

/* Значок «i» в конце заголовка, пояснение в подсказке (ui2/_title_hint.html) */
.title-hint {
  display: inline-flex;
  align-items: center;
  margin-inline-start: 0.375rem;
  padding: 0;
  border: 0;
  background: none;
  color: var(--bs-secondary-color);
  vertical-align: -0.125em;
  cursor: help;
}
.title-hint:hover, .title-hint:focus-visible { color: var(--bs-heading-color); }
.title-hint .lms-icon, .title-hint svg { width: 1.125rem; height: 1.125rem; }
.tooltip-wide { --bs-tooltip-max-width: 20rem; }
.tooltip-wide .tooltip-inner { text-align: start; font-weight: 400; line-height: 1.45; }

/* Таблица превращается в карточки на телефоне: строке ставят
   .table-stack, ячейке data-label="Подпись" */
@media (max-width: 767.98px) {
  .table-stack thead { display: none; }
  .table-stack, .table-stack tbody, .table-stack tr, .table-stack td { display: block; width: 100%; }
  .table-stack tr { padding: 0.75rem 1.25rem; border-bottom: 1px solid var(--bs-border-color); }
  .table-stack td { padding: 0.25rem 0 !important; border: 0 !important; text-align: start !important; }
  .table-stack td[data-label]::before { content: attr(data-label); display: block; color: var(--bs-secondary-color); font-size: 0.75rem; letter-spacing: 0.4px; text-transform: uppercase; }
}

/* Шапка страницы из core/_page_header.html: пояснение и строка беты */
.page-header-main { min-width: 0; flex: 1 1 20rem; }
.page-subtitle { margin: 0.25rem 0 0; color: var(--bs-body-color); max-width: 48rem; }
.page-note { margin: 0.375rem 0 0; color: var(--bs-secondary-color); font-size: 0.8125rem; }
.page-title .badge { font-size: 0.75rem; vertical-align: 0.2em; }

/* Мелочи */
.min-w-0 { min-width: 0; }

/* На телефоне текст полей 16px: при меньшем iOS увеличивает страницу,
   как только нажимаешь на поле. Отступление от Vuexy (у них 15px). */
@media (max-width: 575.98px) {
  .form-control, .form-select, .input-group-text { font-size: 1rem; }
}

/* Проверка контраста 28.09 (apps/ui2/tools/contrast.py) */
/* Счётчик в выбранной вкладке-таблетке: белый на подложке 16 % был 3.8:1 */
.nav-pills .nav-link.active .badge, .nav-link.active .badge.bg-secondary-lt { background: var(--paper) !important; color: var(--primary-text) !important; }
/* Код внутри плашки: розовый на жёлтой подложке 4.1:1, берём цвет плашки */
.alert code { color: inherit; }
/* Метка статуса воронки (static/bots/editor.css): зелёный на светло-зелёном 2.7:1 */
.bx-status-chip[data-status="active"] { color: var(--bs-success-text-emphasis) !important; }
.bx-status-chip[data-status="paused"] { color: var(--bs-warning-text-emphasis) !important; }
/* Поле только для чтения (адрес для копирования): серая подложка к белой
   карточке 1.1:1, форму поля держит рамка той же силы, что у обычного */
.form-control[readonly]:not(:disabled) { border-color: var(--input-border-color); }
/* Поиск во всплывающем окне меток (продажи): цвет браузера #757575 */
.crm-pop__input { color: var(--bs-heading-color); }
.crm-pop__input::placeholder { color: var(--bs-secondary-color); opacity: 1; }
/* Буква курса в тёмной теме: 60 % цвета курса давали 4:1 */
[data-bs-theme="dark"] .course-letter { color: color-mix(in srgb, var(--course-color) 40%, var(--bs-heading-color)); }
