/* КАРАНТИН ВЕНДОРНЫХ ИМЁН (D-51-10). Проверено против Django 6.1.1, 2026-09-15.

   ОБЪЯВЛЕНО ОБРАЩЕНИЙ К ЧУЖИМ ИМЕНАМ: 122
   ОБЪЯВЛЕНО ВЕНДОРНЫХ ПЕРЕМЕННЫХ: 17

   НАЗНАЧЕНИЕ. Тема админки (css/base_admin.css, css/app_list.css, css/custom_admin.css)
   по D-51-01 красит ТОЛЬКО собственные имена с префиксом `qpa-`. Для разметки, которую
   печатает сам Django (фильтры списка, сортируемые заголовки, строки списка приложений,
   крошки, боковая панель) или стороннее приложение (select2, nested_admin), собственное
   имя навесить НЕЛЬЗЯ, не заведя новую вендорную копию шаблона — а D-51-02 копии наоборот
   удаляет. Здесь лежит ровно этот остаток: он не отменён, он ИМЕНОВАН и взят под счёт.

   ЧТО СЮДА НЕ КЛАДУТ: ни одного правила, все имена которого начинаются с `qpa-`. Карантин —
   место для чужих имён, а не вторая тема. Разделение ровное, без зазора и пересечения:
   правило живёт в теме <=> все его имена свои и имя есть хотя бы одно; иначе его адрес здесь.

   ПРИНЯТОЕ ПРАВИЛО СЧЁТА — решение плана 51-09, а не унаследованное число. Оно записано в
   ДВУХ местах: здесь и в коде сторожа calculator/tests/test_theme_selectors.py.

   1. Считает ПАРСЕР селекторных прелюдий; комментарии срезаются ДО разбора. Основание
      замером: вендор сам переформатировал свой CSS между 6.0.7 и 6.1.1 (`'` -> `"`,
      `.6em` -> `0.6em`), и текстовый счёт на таком шумит, а греп вдобавок считает
      ЗАКОММЕНТИРОВАННЫЕ правила.
   2. Единица счёта — одно вхождение имени класса или id, НЕ начинающегося с `qpa-`.
      Словарь вендорных имён НЕ используется вовсе.
   3. Отказ от словаря — решение, а не упрощение: словарь строится по УСТАНОВЛЕННОЙ версии
      Django и физически не видит динамических имён (`model-*`, `field-*`, `app-*`,
      `sortable`), которые рождаются подстановкой. Правило «всё, что не префикс темы»
      покрывает их механически и не требует суждения.
   4. Прелюдия без единого класса и id (`select { }`, `a:link { }`, `input[readonly] { }`)
      считается за ЕДИНИЦУ: имени нет, но обращение к чужой разметке есть. Без этой оговорки
      в карантин можно молча дописать сколько угодно правил, не сдвинув число.
   5. Переопределения вендорных ПЕРЕМЕННЫХ в это число НЕ входят — у них ВТОРОЙ счёт и
      отдельный сторож «имя всё ещё объявлено установленным Django». Два счёта, две проверки.

   ЧИСЛО МОЖЕТ ТОЛЬКО УБЫВАТЬ. Сторож краснеет на РОСТ и молчит на убывание: убывание есть
   продолжение развязки, рост есть её откат. Единственный законный рост — заявленный ЗАРАНЕЕ
   числом, одновременно с правкой, а не обнаруженный после.

   ПОЧЕМУ 121, а не 50 из 51-CONTEXT.md. То число получено ГРЕПОМ по трём файлам темы —
   другой прибор и другая область; в код оно не переносится. Исследование 51-RESEARCH дало
   77 (парсер со словарём вендорных имён) и ~112 (со словарём плюс динамические семейства).
   Замер ЭТИМ правилом даёт 121: правило «всё, что не `qpa-`» видит и динамические имена, и
   сторонние (select2, djn-table), и безымянные прелюдии, которых не видит ни один словарь.

   ПОДКЛЮЧЕНИЕ. Одной строкой в calculator/templates/admin/base_site.html, в
   `{% block extrahead %}` СРАЗУ ПОСЛЕ css/base_admin.css. Порядок обязателен:
   переопределения переменных должны идти ПОСЛЕ вендорных base.css и dark_mode.css, иначе
   тёмный режим отыграет их обратно. (UI-SPEC §5.3.2 называет блок `extrastyle` — такого
   блока в base_site.html нет; замер найден грепом, исполняется замер.)

   ВЕРДИКТ D-51-09 (.artifacts/51-06/flex-verdict.md, исход A «принять колонку»): правил на
   `.flex-container` в тему НЕ добавляется, и объявленный счёт от этого НЕ растёт. */

html[data-theme="light"], :root {
  --secondary: #73326e;
  --breadcrumbs-bg: #73326e;
  --link-fg: #73326e;
  --link-hover-color: #b855bd;
  --button-hover-bg: #b855bd;
  --default-button-hover-bg: #b855bd;
  --default-button-bg: #73326e;
}

html[data-theme="dark"], :root {
  --secondary: #73326e;
  --breadcrumbs-bg: #73326e;
  --link-fg: #b855bd;
  --link-hover-color: #73326e;
  --button-hover-bg: #b855bd;
  --default-button-hover-bg: #b855bd;
  --default-button-bg: #73326e;
}

html[data-theme="dark"] #header {
  color: #fff;
}

#site-name a {
  color: #fff !important;
}

#user-tools {
  margin-top: 2px;
  color: #fff !important;
}

#site-name {
  margin-bottom: 7px;
  color: #fff !important;
}


.breadcrumbs {
  display: flex;
  align-items: center;
  gap: 0 24px;
  justify-content: center;
}

/* Вендорные крошки Django 6.1 печатаются тегом `ol`, а не `div` (UI-SPEC §2.3).
   Селектор перенесён `div.breadcrumbs a` -> `ol.breadcrumbs a` ВМЕСТЕ с разметкой:
   старый на `ol` не попадает вовсе, и ссылка досталась бы вендорному
   `ol.breadcrumbs a { color: var(--breadcrumbs-link-fg) }` — замерено rgb(255,255,255)
   вместо эталонных rgb(242,240,238). Элемент `ol` в селекторе нужен для
   СПЕЦИФИЧНОСТИ: голое `.breadcrumbs a` — (0,1,1), вендорное правило — (0,1,2),
   и тема проиграла бы (тот же механизм, что разобран в сводке 51-07, пункт 3).
   Имя `breadcrumbs` остаётся вендорным — счёт карантина D-51-10 НЕ меняется. */
/* ВЫРАВНИВАНИЕ ОСТАТКА +1 px (GAP 2 круга 2). Решение пользователя — «не
   принимать, выровнять».

   ЗАМЕР. Крошки 6.1 печатаются `ol` с пунктами `li`, и вендор задаёт пункту
   СВОЙ размер шрифта (`ol.breadcrumbs li { font-size: 0.875rem }`), отчего
   вычисленная высота строки пункта выходит 20 px против 19 px у прежнего `div`,
   где строку держал strut контейнера. Полоса крошек 39 -> 40 px (замерено
   104->143 против 104->144), и вслед за ней на 1 px уезжает ВСЁ ниже: шапка
   таблицы списка 269 -> 270.

   ЧТО ДЕЛАЕТ ПРАВИЛО. Возвращает пункту ту же строку, какой она была у `div`:
   `normal` — это не подобранное число, а ровно то значение, которым строку
   считал прежний контейнер. Подставлять `19px` литералом нельзя: 19 px — это
   результат вычисления для конкретного шрифта и кегля, и на другом шрифте он
   разойдётся с эталоном ровно так же, как сейчас разошлись 20 против 19.

   ЦЕНА, НАЗВАННАЯ ЗАРАНЕЕ. Имя `breadcrumbs` вендорное, поэтому правило живёт
   в карантине, а объявленный счёт обращений к чужим именам растёт 121 -> 122
   (шапка файла выше и сторож calculator/tests/test_theme_selectors.py считают
   одно и то же число). Это новая точка зависимости от версии Django: если
   вендор ещё раз переделает разметку крошек, пересматривать придётся и её. */
ol.breadcrumbs li {
  line-height: normal;
}

ol.breadcrumbs a {
  color: #f2f0ee;
  transition: all 0.3s;
}

ol.breadcrumbs a:hover {
  color: #fff;
}


#header {
  color: var(--body-bg);
}

table thead th .text a {
  padding: 0;
}

.select2-container--admin-autocomplete .select2-results__option--highlighted[aria-selected] {
  background-color: var(--secondary);
}

.field-brands .flex-container label {
  order: -1;
}

.field-brands option {
  display: none;
}

.help hr {
  background-color: transparent;
}

.hidden {
  display: none !important;
}

select {
  margin-top: 0;
  margin-bottom: 0;
}

.related-widget-wrapper-link {
  display: flex;
  align-items: center;
}

.form-row input[type="checkbox"] {
  vertical-align: -webkit-baseline-middle;
}

.related-widget-wrapper {
  flex-wrap: nowrap;
  margin-bottom: 0;
}

a:link {
  transition: background 0s;
}

th.sortable.sorted {
  padding: 0 8px;
}

table thead th.sorted .sortoptions {
  padding: 8px 5px 5px 5px !important;
}

thead th.sorted .text {
  padding-right: 59px !important;
  padding-top: 8px;
}

#changelist table thead th {
  padding: 0 8px;
}

td.field-is_active img {
  display: block;
  margin-left: 34px;
}

table {
  overflow-x: auto !important;
  overflow-y: hidden !important;
  display: block !important;
}

#content.colMS {
  padding: 0 0 0 23px !important;
  height: 100%;
}

#content.colMS>h1 {
  display: none;
}

#changelist-filter-extra-actions a {
  background-position: left center;
}

#pricelistend_form table,
main.content:has(li.warning) form#othercompanysetting_form table,
#materialsetting_form table {
  overflow: visible !important;
}

#pricelistdevice_form th>table {
  display: table !important;
}

#pricelistdevice_form td>table input[type="checkbox"] {
  width: 86px;
}

input[readonly] {
  outline: none;
  -moz-appearance: textfield;
  appearance: textfield;
  border: none;
  text-align: center;
}

input[readonly]:focus {
  border-color: var(--border-color);
}

table.inline-related.djn-table {
  position: static !important;
}

#content-main {
  position: relative;
}

.object-tools {
  position: absolute !important;
  margin-top: 0 !important;
  right: 14px;
  top: 8px;
}

.inline-group .tabular tr.has_original td {
  padding-top: 8px !important;
  vertical-align: middle !important;
}

#pricelistcompany_form .module,
#pricelistdevice_form .module,
#pricelistsink_form .module {
  margin-bottom: 0 !important;
}

#pricelistcompany_form .module.aligned select {
  min-width: 400px;
}

.model-pricelistdevice .colM,
.model-pricelistsink .colM {
  padding-top: 0 !important;
}

.model-pricelistmaterialprice .object-tools a.addlink {
  background: var(--button-bg);
  padding: 10px 15px;
  border: none;
  border-radius: 4px;
  color: var(--button-fg);
  cursor: pointer;
  transition: background 0.15s;
  font-family: var(--font-family-primary);
  font-weight: normal;
  font-size: 0.8125rem;
  text-transform: none;
  line-height: normal;
  margin: 2px 0;
}

.object-tools a.addlink:hover {
  background: var(--button-hover-bg);
}

#changelist-filter {
  margin: 46px 0 0 30px;
}
th.sortable #changelist-filter {
  margin: 6px 0 0 0;
}
th.sortable #changelist-filter ul{
  padding-bottom: 0;
  padding-left: 0;
}
.changelist-form-container.has-filters {
  display: flex;
  flex-wrap: nowrap;
  align-items: flex-start;
  width: 100%;
}
.changelist-form-container.has-filters > div {
  flex: 1 1 0;
  width: 0;
  max-width: calc(100% - 270px);
  min-width: 0;
}
.select2-search:has(.select2-search__field[aria-controls="select2-id-material_type__pk__exact-dal-filter-results"]) {
  display: none;
}
#pricelistend_form .qpa-select--selected {
  height: 45px;
  display: flex;
  align-items: center;
}

#pricelistend_form .qpa-select p {
  width: 60px;
}

#pricelistend_form .qpa-select img {
  max-width: 45px;
}

#pricelistend_form .qpa-select__items div {
  display: flex;
  align-items: center;
}

.app-pricelists.current-app tbody {
  display: flex;
  flex-direction: column;
}

.app-pricelists.current-app .model-pricelistoperation {
  order: -7;
}

.app-pricelists.current-app .model-pricelistend {
  order: -6;
}

.app-pricelists.current-app .model-pricelistdevice {
  order: -5;
}

.app-pricelists.current-app .model-pricelistmaterialprice {
  order: -4;
}

.app-pricelists.current-app .model-pricelistsink {
  order: -3;
}

.app-pricelists.current-app .model-pricelistservice {
  order: -2;
}

.field-brands .flex-container .help-tooltip {
  order: -2;
}

th.sortable .select2-container--admin-autocomplete .select2-selection--single .select2-selection__placeholder {
  color: var(--body-fg);
  text-transform: none;
  font-weight: 400;
}
@media screen and (max-width: 768px) {
  ol.breadcrumbs a {
    font-size: 0;
  }
}

/* --- ниже переехало из css/app_list.css (та же развязка, тот же адрес) ---

   ОБЛАСТЬ ЭТИХ ПРАВИЛ ЗАДАНА СЕЛЕКТОРОМ, А НЕ ФАКТОМ ПОДКЛЮЧЕНИЯ ФАЙЛА.
   css/app_list.css подключается изнутри `custom_admin/app_list.html` и
   `custom_admin/app_index.html`, то есть ровно там, где рендерится
   `custom_admin/app_table.html` — замером это ДВЕ страницы из тринадцати
   (custom-app-index и custom-changelist). Карантин подключён на ОДИННАДЦАТИ, и
   переезд без восстановления области — молчаливое расширение: замер поймал его
   числом, `B-10.высота шапки таблицы 33 -> 31` на admin-changelist и
   admin-changelist-user, то есть правило доехало до ПЕРВОЙ админки, где его
   никогда не было.

   Область восстановлена признаком САМОЙ разметки: `body:has(.qpa-admin-menu)`
   истинно ровно тогда, когда на странице отрисован app_table.html — он и есть
   то, ради чего файл подключался. Специфичность от приставки только РАСТЁТ, то
   есть правило продолжает выигрывать те же споры, что выигрывало последним
   подключённым файлом. --- */

body:has(.qpa-admin-menu) table thead th .text span {
  padding: 0px;
}

body:has(.qpa-admin-menu) .current-model {
  background-color: #f0f0f0; /* Light gray background for current model */
}

body:has(.qpa-admin-menu) #nav-sidebar th a {
  font-size: 16px;
  color: var(--body-loud-color);
  text-transform: uppercase;
  display: block;
}

body:has(.qpa-admin-menu) #nav-sidebar .current-model {
  background: var(--breadcrumbs-bg);
}

body:has(.qpa-admin-menu) #nav-sidebar .current-model th a {
  color: #fff;
  font-weight: 500;
}

body:has(.qpa-admin-menu) #nav-sidebar {
  transition: 0.3s ease-in;
}

body:has(.qpa-admin-menu) .toggle-nav-sidebar::before {
  color: var(--header-bg);
}
