/*
 * Переопределения стилей MoonShine-админки.
 * Подключается глобально в App\Providers\MoonShineServiceProvider::boot()
 * через moonshineAssets()->append() — на всех layout'ах, включая логин.
 */

/*
 * TomSelect (single + searchable): пока открыт выпадающий список, прячем
 * выбранный элемент из контрола, чтобы имя предыдущего выбора не
 * оставалось рядом с набираемым текстом. Текущий выбор при этом
 * подсвечен в выпадающем списке; после выбора (Enter/клик) список
 * закрывается и имя сразу видно — по input-active нельзя, т.к. фокус
 * остаётся на поле и после выбора, и строка выглядела пустой.
 */
select[data-search-enabled] + .ts-wrapper.single.dropdown-active .ts-control > .item {
    display: none;
}

/*
 * W7 (docs/UI_UX_POLISH_TASK.md): вложенные пункты сайдбара визуально
 * мельче и с отступом слева, чтобы отличаться от заголовков групп.
 * .menu-submenu — вендорный класс вложенного <ul> (menu/index.blade.php,
 * $dropdown=true), рендерится только внутри открытой группы.
 */
.menu-submenu {
    padding-left: 0.75rem;
}

.menu-submenu .menu-text {
    font-size: 0.9em;
}

/*
 * docs/SIDEBAR_JUMP_TASK.md §0.4: 'sidebar-preload' ставится синхронно на
 * <html> в <head> (MoonShineLayout::assets(), InlineJs без defer) ДО
 * первого пейнта и снимается в moonshine-custom.js после того, как
 * restore() применит открытые группы (localStorage
 * 'neho:sidebar:openGroups') и scrollTop ('neho:sidebar:scrollTop') на
 * 'alpine:initialized'. Пока класс висит: (1) сам список меню скрыт —
 * пользователь не видит сброшенное (закрыто/scrollTop=0) состояние ДО
 * того, как JS восстановит реальное; (2) collapse-анимация группы
 * (x-transition.top, group.blade.php) отключена — восстановление не
 * должно выглядеть как раскрытие группы кликом.
 */
html.sidebar-preload .layout-menu .menu-list {
    visibility: hidden;
}

html.sidebar-preload .menu-item,
html.sidebar-preload .menu-submenu {
    transition: none !important;
}

/*
 * §2 (docs/SIDEBAR_JUMP_TASK.md): вендорный `.menu-list` (main.css)
 * намеренно прячет системный scrollbar (`scrollbar-width:none` +
 * `::-webkit-scrollbar{display:none}`) — при меню длиннее экрана это
 * единственный способ прокрутки мышью/тачем без визуального индикатора
 * позиции ("скролл только колёсиком", жалоба владельца). Тонкий
 * стилизованный scrollbar поверх текущей цветовой схемы — переменные
 * `--ms-cm-base-*` уже определены в color-schemes.css под обе темы
 * ([data-scheme]), значения сами переключаются вместе со схемой.
 * `.layout-menu .menu-list` (2 класса) специфичнее вендорного `.menu-list`
 * (1 класс) — переопределяет каскадом без !important.
 */
.layout-menu .menu-list {
    scrollbar-width: thin;
    scrollbar-color: var(--ms-cm-base-400) transparent;
}

.layout-menu .menu-list::-webkit-scrollbar {
    display: block;
    width: 6px;
}

.layout-menu .menu-list::-webkit-scrollbar-track {
    background: transparent;
}

.layout-menu .menu-list::-webkit-scrollbar-thumb {
    background-color: var(--ms-cm-base-400);
    border-radius: 3px;
}

.layout-menu .menu-list::-webkit-scrollbar-thumb:hover {
    background-color: var(--ms-cm-base-600);
}

/*
 * W5 (docs/UI_UX_POLISH_TASK.md): карточки дашборда — сейчас у вендорного
 * Column только col-span-{adaptive}/xl:col-span-{colSpan}, т.е. один
 * брейкпоинт (xl=1280px), сетка скачет 4->1. Добавляем промежуточные шаги
 * 3 и 2 колонки поверх existing col-span-12 (<640px, без изменений) и
 * xl:col-span-3 (>=1280px, без изменений). Верхняя граница 1023px — граница
 * встроенного вендорного авто-burger сайдбара (.layout-menu, main.css,
 * @media not all and (min-width:1024px)), поэтому "<=2 колонки -> сайдбар
 * в бургер" уже выполняется существующим поведением, без доп. правок.
 */
@media (min-width: 640px) and (max-width: 1023px) {
    .dashboard-grid > div {
        grid-column: span 6 / span 6;
    }
}

@media (min-width: 1024px) and (max-width: 1279px) {
    .dashboard-grid > div {
        grid-column: span 4 / span 4;
    }
}

/*
 * W3 (docs/UI_UX_POLISH_TASK.md): переключатель языка — двухбуквенный код
 * вместо иконки-глифа (resources/views/vendor/moonshine/components/layout/
 * locales.blade.php). Фиксированная ширина, чтобы разные коды (2 буквы)
 * не дёргали раскладку топбара.
 */
.languages-btn-code {
    display: inline-block;
    min-width: 1.6em;
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-align: center;
}

/*
 * W11 (docs/UI_STANDARDS_TASK.md блок 1): шрифт панели фильтров и выпадающего
 * меню выбора колонок — ~на 20% меньше основного.
 *
 * Панель фильтров рендерится как .offcanvas (MoonShine\Crud\Buttons\
 * FiltersButton::for() -> ActionButton::inOffCanvas()) — единственное место
 * в проекте, где используется этот компонент, поэтому селектор безопасен
 * (не заденет ничего другого).
 *
 * Меню выбора колонок — обычный .dropdown (TableBuilder::getTopRight()),
 * этот же компонент используется по всему проекту (профиль, языки,
 * уведомления, действия строки таблицы) — сузить пришлось через :has() по
 * маркеру data-column-selection-checker, который вендор уже вешает именно
 * на чекбоксы колонок (тот же файл TableBuilder.php) и больше нигде.
 */
.offcanvas {
    font-size: 0.8em;
}

.dropdown:has([data-column-selection-checker]) .dropdown-menu {
    font-size: 0.8em;
}

/*
 * W16 (docs/UI_STANDARDS_TASK.md блок 2): компактные формы простых
 * справочников — App\MoonShine\Resources\Concerns\HasCompactFormLayout
 * добавляет класс .form-compact на <form> (FormPage::modifyFormComponent())
 * и .field-compact на wrapper коротких полей (Field::wrapperClass(),
 * вызывается через $this->compact($field) в fields()).
 *
 * Каждое поле рендерится вендором как <div class="form-group moonshine-field">
 * прямым ребёнком <form> (form-container.blade.php); кнопки внизу формы —
 * тоже прямой ребёнок <form>, но НЕ .moonshine-field (свой Grid/Column) —
 * :not(.moonshine-field) возвращает его на полную ширину без знания
 * конкретного класса.
 */
form.form-compact {
    display: flex;
    flex-wrap: wrap;
    gap: 0 1rem;
    max-width: 720px;
}

form.form-compact > .moonshine-field {
    flex: 1 1 100%;
}

form.form-compact > .moonshine-field.field-compact {
    flex: 1 1 200px;
    max-width: calc(33.333% - 0.75rem);
}

form.form-compact > :not(.moonshine-field) {
    flex: 1 1 100%;
}

/* W27 (docs/FOOTER_FIXPACK_TASK.md): ряд иконок соцсетей в футере. */
.neho-footer-social {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin-left: 0.75rem;
}

.neho-footer-social-link {
    display: inline-flex;
    opacity: 0.7;
}

.neho-footer-social-link:hover {
    opacity: 1;
}

/* docs/UI_SEARCH_2_TASK.md §1: единый тулбар «[поиск……][⇕]» в одну строку
   — общий flex-родитель, обёрнутый в MoonShineLayout::sidebarSlot()
   (Div::make([global-search, sidebar-toggle-all])). Горизонтальные
   отступы и скрытие в mini-сайдбаре/горизонтальном/мобильном меню теперь
   на уровне тулбара, а не у каждого блока по отдельности — сами блоки
   внутри просто растягиваются/прижимаются flex-параметрами. */
.neho-sidebar-toolbar {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.25rem 0.75rem 0.5rem;
}

.neho-sidebar-toolbar .neho-global-search {
    flex: 1 1 auto;
    min-width: 0;
    padding: 0;
}

.neho-sidebar-toolbar .neho-sidebar-toggle-row {
    flex: 0 0 auto;
    padding: 0;
}

.layout-menu._is-minimized .neho-sidebar-toolbar,
.layout-menu-horizontal .neho-sidebar-toolbar,
.layout-menu-mobile .neho-sidebar-toolbar {
    display: none;
}

/* W28 (docs/SIDEBAR_TOGGLE_TASK.md): один переключатель +/- групп сайдбара. */
.neho-sidebar-toggle-row {
    display: flex;
    justify-content: flex-end;
    padding: 0.25rem 0.75rem;
}

.neho-sidebar-toggle-all {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border: 1px solid currentColor;
    border-radius: 4px;
    opacity: 0.6;
    font-size: 13px;
    line-height: 1;
}

.neho-sidebar-toggle-all:hover {
    opacity: 1;
}

/* docs/UI_SEARCH_TASK.md (а): строка глобального поиска. */
.neho-global-search {
    position: relative;
    padding: 0.25rem 0.75rem 0.5rem;
}

.neho-global-search-field {
    position: relative;
    display: flex;
    align-items: center;
}

.neho-global-search-icon {
    position: absolute;
    left: 0.5rem;
    opacity: 0.5;
    pointer-events: none;
}

.neho-global-search-input {
    width: 100%;
    padding: 0.375rem 0.5rem 0.375rem 1.75rem;
    border: 1px solid var(--color-base-stroke, currentColor);
    border-radius: var(--radius-lg, 6px);
    background: var(--color-base, transparent);
    color: var(--color-base-text, inherit);
    font-size: var(--text-sm, 0.8125rem);
}

.neho-global-search-dropdown {
    position: absolute;
    z-index: 40;
    top: 100%;
    left: 0.75rem;
    right: 0.75rem;
    margin-top: 0.25rem;
    max-height: 60vh;
    overflow-y: auto;
    background: var(--color-base, #fff);
    border: 1px solid var(--color-base-stroke, currentColor);
    border-radius: var(--radius-lg, 6px);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}

.neho-global-search-status {
    padding: 0.5rem 0.75rem;
    opacity: 0.6;
    font-size: var(--text-sm, 0.8125rem);
}

.neho-global-search-group {
    padding: 0.25rem 0;
}

.neho-global-search-group + .neho-global-search-group {
    border-top: 1px solid var(--color-base-stroke, currentColor);
}

.neho-global-search-group-title {
    padding: 0.25rem 0.75rem;
    font-size: 0.6875rem;
    text-transform: uppercase;
    opacity: 0.5;
}

.neho-global-search-item {
    display: flex;
    flex-direction: column;
    padding: 0.375rem 0.75rem;
}

.neho-global-search-item:hover {
    background: var(--color-base-50, rgba(0, 0, 0, 0.05));
}

.neho-global-search-item-title {
    font-size: var(--text-sm, 0.8125rem);
}

.neho-global-search-item-subtitle {
    font-size: 0.6875rem;
    opacity: 0.6;
}

.neho-global-search-show-all {
    display: block;
    padding: 0.375rem 0.75rem;
    font-size: var(--text-sm, 0.8125rem);
    font-weight: 600;
}

.neho-global-search-show-all:hover {
    text-decoration: underline;
}

/* W29 (docs/SIDEBAR_TOGGLE_TASK.md): один пункт «Цветовая схема» в меню
   пользователя, клик раскрывает список схем аккордеоном под ним (не
   flyout вбок — .dropdown-body вендора обрезает по overflow: hidden,
   см. докблок profile-scheme-menu-item.blade.php). */
.neho-scheme-menu-title {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.neho-scheme-menu-arrow {
    margin-left: auto;
    width: 14px;
    height: 14px;
    transition: transform 0.15s ease;
}

.neho-scheme-menu-arrow.rotate-180 {
    transform: rotate(180deg);
}

.neho-scheme-submenu {
    padding-left: 1.25rem;
}

.neho-scheme-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

.neho-scheme-check {
    opacity: 0;
}

/* Активная схема отмечена чистым CSS-совпадением :root[data-scheme] с
   data-color-scheme ссылки — она может быть применена и из localStorage,
   серверный флаг не всегда совпадал бы с реальной. Один селектор на схему;
   ponytail: при добавлении 6-й схемы в ColorSchemeRegistry добавить сюда
   ещё одну строку. */
:root[data-scheme="neho-blue"] [data-color-scheme="neho-blue"] .neho-scheme-check,
:root[data-scheme="sand-light"] [data-color-scheme="sand-light"] .neho-scheme-check,
:root[data-scheme="slate-dark"] [data-color-scheme="slate-dark"] .neho-scheme-check,
:root[data-scheme="midnight-dark"] [data-color-scheme="midnight-dark"] .neho-scheme-check,
:root[data-scheme="colorblind-safe"] [data-color-scheme="colorblind-safe"] .neho-scheme-check {
    opacity: 1;
}

/*
 * B1 (UX-2, docs/uat/2026-07-16-raw-materials-uat-session.md): вендорный
 * .form-group (form/wrapper.blade.php — обёртка label+поле) держит
 * вертикальный зазор label->поле через --ms-form-group-gap (дефолт
 * --spacing(2), forms.css) — уменьшаем, чтобы компактная Grid/Column-
 * раскладка коротких полей (см. BuildsNomenclatureFormFields) не терялась
 * из-за лишней высоты каждого отдельного поля. Общий для всех форм
 * MoonShine (не только номенклатуры) — тот же запрос применим ко всем
 * растянутым формам (UX-2: «касается почти всех форм»).
 */
.form-group {
    --ms-form-group-gap: 0.25rem;
}

/*
 * B7 (UX-37, docs/uat/2026-07-16-raw-materials-uat-session.md) +
 * ui-navigation-standard п.1 (регресс «модалка опять гуляет»): у вендорной
 * модалки (moonshine components/modals.css) flex-центрирование живёт НЕ на
 * .modal, а на .modal-dialog (`display:flex; align-items:center;
 * min-height: calc(100% - ...)`), т.е. .modal-content центрируется по
 * вертикали внутри диалога во всю высоту экрана. При переключении вкладок
 * внутри модалки (напр. «Добавить спецификацию»: Пищевая ценность/Упаковка/
 * Источники усреднения) высота содержимого меняется — центр пересчитывается
 * заново, и окно визуально прыгает.
 *
 * РЕГРЕСС: прошлый фикс правил `.modal { align-items: flex-start }`, но .modal
 * у вендора вообще не flex-контейнер (`position:fixed; overflow-y:auto`) — то
 * правило было no-op, а `align-items:center` на .modal-dialog продолжало
 * центрировать → модалка «гуляла» снова. Правильная точка — сам .modal-dialog:
 * выравниваем его содержимое по верху (flex-start) + постоянный отступ сверху.
 * Тогда при смене высоты контента растёт/сжимается только низ, верх неподвижен.
 * Общий фикс для ВСЕХ модалок (обычных/wide/full/auto — селектор .modal-dialog
 * покрывает все варианты). Регрессию стережёт ModalTopAlignedCssTest.
 */
.modal-dialog {
    align-items: flex-start;
    margin-top: 4vh;
}

/* UX-30 (docs/uat/2026-07-16-raw-materials-uat-session.md): подсветка
   действующей (is_current) версии спецификации в реестре — форма, а не
   только цвет (левая рамка), чтобы не зависеть от восприятия цвета
   (тот же принцип, что W15 boolean-иконки ✓/✗). */
tr.row-current-specification {
    border-left: 3px solid var(--color-primary, #2563eb);
}

/*
 * B8 (UX-39, docs/UAT_RAW_2_TASK.md блок 1): конвенция «иконка + tooltip»
 * для ActionButton — подпись остаётся в разметке (App\MoonShine\Support\UI\
 * IconOnlyLabel::make() оборачивает текст в этот класс) ради доступности
 * (screen reader читает текст), но визуально скрыта тем же приёмом, что
 * стандартный Tailwind .sr-only — не полагаемся на то, что вендорный бандл
 * его подключает, определяем локально.
 */
.icon-only-label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/*
 * Блок 12 (P24, docs/UAT_PACKAGING_TASK.md): полный текст превью состава
 * на этикетке (BOM/секретный BOM) усечён визуально до 3 строк — строка
 * таблицы больше не растягивается на весь экран, полный текст доступен
 * по клику (App\MoonShine\Support\UI\ClampedTextPreview).
 */
.line-clamp-preview {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/*
 * docs/MENU_STRUCTURE_TASK.md, Часть 2 "Разделители-секций": подпись
 * MenuDivider, вставленного App\MoonShine\MenuManager\SectionedMenuAutoloader
 * внутри крупных объединённых групп бокового меню (Склад/Производство/
 * Качество/Справочники/Система), должна быть заметно мельче обычного
 * пункта меню — 25% меньше, ОТНОСИТЕЛЬНОЙ единицей от текущего размера
 * шрифта пункта (не абсолютным px, чтобы не рассинхронизироваться при
 * смене темы/масштаба). Вендорную .menu-divider (divider.blade.php,
 * MoonShine CSS) не трогаем — правим только свой класс.
 */
.menu-section-divider span {
    font-size: .75em;
}

/*
 * docs/DEMO_BRANDING_FIXPACK_2_TASK.md факт 6: вендорный MoonShine CSS
 * форсит логотипу h-14 (3.5rem). Владелец хочет лого на СТРАНИЦЕ ЛОГИНА
 * заметно крупнее (~2-3x), а в сайдбаре — чуть крупнее. Правим свои
 * оверрайды (append после vendor main.css → каскад выигрывает), не трогая
 * вендорный файл (ломается при composer update).
 * ponytail: высоты подобраны на глаз (2.4x / чуть крупнее) — интегратор
 * подстроит под реальный логотип демо-стенда, физический размер картинки
 * минимальной моделью не угадать.
 */
.authentication-logo .logo img {
    height: 8.5rem;
    max-height: 8.5rem;
    width: auto;
}

.menu-logo .logo img {
    height: 2.75rem;
    max-height: 2.75rem;
    width: auto;
}

/*
 * ui-navigation-standard п.4(а): выпадашка «Ещё…» для переросших вкладок
 * (public/js/moonshine-custom.js выносит в неё вкладки, не влезшие в строку).
 * Наличие .tabs-more не форсируем через nowrap: если JS не отработал, вкладки
 * просто переносятся, как раньше (безопасный фолбэк) — «Ещё» лишь улучшает.
 */
.tabs-more {
    position: relative;
}

.tabs-more-list {
    display: none;
    position: absolute;
    right: 0;
    top: 100%;
    z-index: 40;
    min-width: 12rem;
    margin: 0;
    padding: 0.25rem;
    list-style: none;
    background-color: var(--ms-modal-content-bg-color, var(--color-base, #fff));
    border: 1px solid var(--color-base-stroke, rgba(0, 0, 0, 0.1));
    border-radius: var(--radius-lg, 0.5rem);
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
}

.tabs-more.open .tabs-more-list {
    display: block;
}

.tabs-more-list .tabs-item {
    display: block;
    width: 100%;
}

.tabs-more-toggle {
    white-space: nowrap;
}

/*
 * ui-navigation-standard (довесок): часы сервера в шапке админки.
 */
.neho-server-clock {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    opacity: 0.85;
}

.neho-server-clock-skew {
    color: #d97706;
    cursor: help;
}

/*
 * connection-indicator: «светофор» связи рядом с часами.
 * Зелёный = сервер отвечает быстро, жёлтый = отвечает, но медленно/5xx,
 * красный = таймаут/сеть/не-ответ. Красный пульсирует, чтобы заметить без
 * наведения. Цвета — фиксированные семафорные (смысл не должен меняться со
 * сменой темы). Попап и баннер используют темовые --color-base* переменные,
 * как остальные кастомные тултипы этого файла.
 */
.neho-conn-indicator {
    position: relative;
    display: inline-flex;
    align-items: center;
    cursor: pointer;
    padding: 0 0.15rem;
}

.neho-conn-dot {
    width: 0.6rem;
    height: 0.6rem;
    border-radius: 50%;
    background: #9ca3af; /* серый — до первого пинга */
    box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.05);
    transition: background-color 0.3s ease;
}

.neho-conn-indicator[data-state="ok"] .neho-conn-dot {
    background: #16a34a;
}

.neho-conn-indicator[data-state="slow"] .neho-conn-dot {
    background: #d97706;
}

.neho-conn-indicator[data-state="down"] .neho-conn-dot {
    background: #dc2626;
    animation: neho-conn-pulse 1.2s ease-in-out infinite;
}

@keyframes neho-conn-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.35; }
}

.neho-conn-popup {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    z-index: 100;
    min-width: 190px;
    padding: 0.5rem 0.65rem;
    border-radius: var(--radius-lg, 6px);
    background: var(--color-base, #fff);
    color: var(--color-base-text, inherit);
    border: 1px solid var(--color-base-stroke, rgba(0, 0, 0, 0.15));
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
    font-size: var(--text-sm, 0.8rem);
    line-height: 1.4;
    white-space: normal;
    text-align: left;
}

.neho-conn-popup[hidden] {
    display: none;
}

.neho-conn-popup-status {
    font-weight: 600;
}

.neho-conn-form-warning {
    position: fixed;
    left: 50%;
    bottom: 1rem;
    transform: translateX(-50%);
    z-index: 90;
    max-width: 92vw;
    padding: 0.5rem 0.9rem;
    border-radius: var(--radius-lg, 6px);
    background: #dc2626;
    color: #fff;
    font-size: 0.85rem;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
}

.neho-conn-form-warning[hidden] {
    display: none;
}
