/* ===========================================================================
   Общие стили DocLibs
   =========================================================================== */

/* ===========================================================================
   Сайдбар знаний
   =========================================================================== */

.knowledge-sidebar .card-body {
    max-height: calc(100vh - 140px);
    overflow-y: auto;
    overflow-x: hidden;
}

.knowledge-tree-scroll {
    overflow-y: auto;
    overflow-x: hidden;
}

/* Дерево знаний */
.knowledge-tree {
    font-size: 0.9rem;
    line-height: 1.4;
    margin: 0;
    padding: 0;
    list-style: none;
}

.knowledge-tree-depth-1 {
    padding-left: 0.75rem;
    border-left: 1px solid #e9ecef;
    margin-left: 0.75rem;
}

.knowledge-tree-depth-2 {
    padding-left: 0.75rem;
    border-left: 1px solid #e9ecef;
    margin-left: 0.75rem;
}

.knowledge-tree-item {
    margin-bottom: 1px;
}

.knowledge-tree-row {
    padding: 2px 0;
    border-radius: 4px;
}

.knowledge-tree-row:hover {
    background-color: #f8f9fa;
}

.knowledge-tree-row.active {
    background-color: #e7f1ff;
}

.knowledge-tree-toggle {
    background: none;
    border: none;
    padding: 0;
    width: 18px;
    height: 18px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    color: #6c757d;
    flex-shrink: 0;
    font-size: 0.7rem;
    transition: transform 0.15s ease;
}

.knowledge-tree-toggle:hover {
    color: #0d6efd;
}

.knowledge-tree-toggle.expanded .knowledge-tree-chevron {
    transform: rotate(90deg);
    display: inline-block;
}

.knowledge-tree-toggle-placeholder {
    display: inline-block;
    width: 18px;
    flex-shrink: 0;
}

.knowledge-tree-link {
    text-decoration: none;
    display: flex;
    align-items: center;
    flex-grow: 1;
    padding: 2px 4px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.knowledge-tree-link:hover {
    text-decoration: underline;
}

/* Дети скрыты по умолчанию */
.knowledge-tree-children {
    display: none;
}

.knowledge-tree-children.expanded {
    display: block;
}

/* ===========================================================================
   Мобильная модалка с деревом
   =========================================================================== */

#mobileTreeModal .modal-body {
    padding-top: 0.5rem;
}

#mobileTreeModal .knowledge-tree {
    font-size: 0.95rem;
}

/* ===========================================================================
   Хлебные крошки
   =========================================================================== */

.breadcrumb {
    margin-bottom: 1rem;
}

.breadcrumb-item + .breadcrumb-item::before {
    content: '/';
    color: #adb5bd;
}

@media (max-width: 767.98px) {
    .breadcrumb .d-none.d-md-inline {
        display: none !important;
    }
}

/* ===========================================================================
   Статьи базы знаний
   =========================================================================== */

.article-content {
    line-height: 1.7;
    color: #212529;
}

.article-content h2 {
    font-size: 1.4rem;
    margin-top: 2rem;
    margin-bottom: 1rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid #e9ecef;
}

.article-content h3 {
    font-size: 1.15rem;
    margin-top: 1.5rem;
    margin-bottom: 0.75rem;
}

.article-content h4 {
    font-size: 1.05rem;
    margin-top: 1.25rem;
    margin-bottom: 0.5rem;
}

.article-content p {
    margin-bottom: 1rem;
}

.article-content ul,
.article-content ol {
    margin-bottom: 1rem;
    padding-left: 1.5rem;
}

.article-content li {
    margin-bottom: 0.25rem;
}

.article-content blockquote {
    border-left: 4px solid #dee2e6;
    padding: 0.5rem 1rem;
    margin: 1rem 0;
    color: #6c757d;
    background: #f8f9fa;
    border-radius: 0 4px 4px 0;
}

/* Inline-код */
.article-content code:not([class*="language-"]) {
    background: #f0f2f4;
    color: #d63384;
    padding: 2px 6px;
    border-radius: 4px;
    font-size: 0.875em;
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
}

/* Блоки кода */
.article-content pre {
    background: #f6f8fa;
    border: 1px solid #e9ecef;
    border-radius: 6px;
    padding: 12px 16px;
    overflow-x: auto;
    font-size: 0.85rem;
    line-height: 1.5;
    margin: 1rem 0;
}

.article-content pre code {
    background: transparent;
    color: inherit;
    padding: 0;
    font-size: inherit;
    border-radius: 0;
}

/* Таблицы */
.article-content table {
    width: 100%;
    margin: 1rem 0;
    border-collapse: collapse;
    font-size: 0.9rem;
}

.article-content table th,
.article-content table td {
    padding: 8px 12px;
    border: 1px solid #dee2e6;
}

.article-content table th {
    background: #f8f9fa;
    font-weight: 600;
    text-align: left;
}

.article-content table tr:nth-child(even) td {
    background: #fcfcfd;
}

/* Изображения */
.article-content img {
    max-width: 100%;
    height: auto;
    border-radius: 6px;
    margin: 0.5rem 0;
}

/* Ссылки */
.article-content a {
    color: #0d6efd;
    text-decoration: none;
}

.article-content a:hover {
    text-decoration: underline;
}

/* Горизонтальная линия */
.article-content hr {
    margin: 1.5rem 0;
    border: 0;
    border-top: 1px solid #e9ecef;
}

/* ===========================================================================
   Кнопка «Наверх»
   =========================================================================== */

.back-to-top {
    position: fixed;
    bottom: 24px;
    right: 24px;
    width: 42px;
    height: 42px;
    border-radius: 50%;
    background: #0d6efd;
    color: #fff;
    border: none;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    cursor: pointer;
    display: none;
    align-items: center;
    justify-content: center;
    font-size: 1.2rem;
    z-index: 1000;
    transition: opacity 0.2s;
}

.back-to-top.visible {
    display: flex;
}

.back-to-top:hover {
    background: #0b5ed7;
}

/* ===========================================================================
   Flexi-Editor
   =========================================================================== */

#content-editor {
    min-height: 400px;
    font-size: 0.95rem;
}

/* Внутри редактора: код с Prism */
#content-editor pre {
    background: #f6f8fa;
    border: 1px solid #e9ecef;
    border-radius: 6px;
    padding: 12px 16px;
    overflow-x: auto;
    font-size: 0.85rem;
}

#content-editor pre code {
    background: transparent;
    padding: 0;
}

/* Таблицы внутри редактора */
#content-editor table {
    width: 100%;
    margin: 1rem 0;
    border-collapse: collapse;
}

#content-editor table th,
#content-editor table td {
    padding: 6px 10px;
    border: 1px solid #dee2e6;
}

#content-editor table th {
    background: #f8f9fa;
}

/* ===========================================================================
   Адаптивность
   =========================================================================== */

@media (max-width: 767.98px) {
    .article-content h2 {
        font-size: 1.2rem;
    }
    .article-content h3 {
        font-size: 1.05rem;
    }
    .article-content {
        font-size: 0.95rem;
    }
    #content-editor {
        min-height: 300px;
        font-size: 0.9rem;
    }
}

/* ===========================================================================
   Плавная прокрутка
   =========================================================================== */

html {
    scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }
}

/* TOAST UI Editor: интеграция с общим стилем */
.toastui-editor-defaultUI {
    border: 1px solid #e9ecef;
    border-radius: 6px;
}

.toastui-editor-contents {
    font-family: inherit;
    font-size: 0.95rem;
}

/* Дерево проектов */
.project-tree {
    font-size: 0.9rem;
    line-height: 1.5;
    margin: 0;
    padding: 0;
    list-style: none;
}

.project-tree-children {
    padding-left: 1.5rem;
    border-left: 2px solid #e9ecef;
    margin-left: 0.5rem;
    margin-top: 0.25rem;
    margin-bottom: 0.5rem;
}

.project-tree-item {
    margin-bottom: 0.25rem;
}

.project-tree-row {
    border-radius: 4px;
    padding: 4px 8px;
    transition: background-color 0.15s;
}

.project-tree-row:hover {
    background-color: #f8f9fa;
}

mark {
    background-color: #fff3cd;
    padding: 0 2px;
    border-radius: 2px;
}

/* Шапка: аватарка пользователя */
.user-avatar-circle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background-color: #0d6efd;
    color: #fff;
    font-weight: 600;
    font-size: 0.875rem;
    text-transform: uppercase;
    flex-shrink: 0;
}

/* Шапка: поле поиска. Ширина постоянная — от неё зависит разбор пунктов меню в «Ещё». */
.header-search {
    width: 220px;
}

.header-search .input-group-text {
    color: #6c757d;
}

.header-search .form-control:focus {
    box-shadow: none;
    border-color: #ced4da;
}

@media (max-width: 991.98px) {
    .header-search {
        width: 100%;
    }
}

/*
 * Шапка: меню в одну строку, лишние пункты — в кнопку «Ещё».
 *
 * Владелец (05.10.2026): меню не должно переноситься на вторую строку. Оно держится
 * одной строкой до поиска, а пункты, которым не хватило ширины, уезжают в выпадающий
 * список «Ещё» (public/js/header-menu.js) — в том же порядке значимости.
 * Класс menu-oneline ставит скрипт: пока он не отмерил ширину, меню переносится как раньше,
 * и без JavaScript вёрстка остаётся рабочей (просто в две строки).
 */
.navbar .navbar-collapse {
    min-width: 0;
}

.navbar .navbar-nav {
    row-gap: .1rem;
}

.navbar.header-nav.menu-oneline .header-menu {
    flex-wrap: nowrap;
}

/*
 * Пункт меню не переносит текст внутри себя: ширина пункта должна быть «настоящей»,
 * иначе перенос внутри ссылки обманывает расчёт в header-menu.js (пункты «выглядят»
 * узкими, а по факту занимают две строки).
 */
.navbar.header-nav .header-menu .nav-link {
    white-space: nowrap;
}

/*
 * Имя пользователя в шапке показываем только на очень широких экранах:
 * оно забирает у меню больше места, чем все пункты вместе (владелец: приоритет —
 * пункты меню в одну строку). На остальных экранах пользователь виден по аватарке
 * с подсказкой, а имя есть в выпадающем списке профиля.
 */
.header-user-name {
    display: none;
}

@media (min-width: 1760px) {
    .header-user-name {
        display: inline;
    }
}

.header-more .dropdown-menu {
    max-width: 18rem;
}

.header-more .dropdown-item.active,
.header-more .dropdown-item:active {
    background-color: #e7f1ff;
    color: #0d6efd;
}

@media (max-width: 1500px) {
    .navbar .nav-link {
        padding-left: .55rem;
        padding-right: .55rem;
    }

    .header-search {
        width: 170px;
    }
}

/* Главная: hero-блок */
.hero-block {
    padding: 1.5rem 0;
}

/* Главная: карточки разделов */
.section-card {
    border: 1px solid #e9ecef;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.section-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08) !important;
}

.section-card-icon {
    font-size: 2.5rem;
    line-height: 1;
}

/* Главная: цифры краткой статистики.
   Метрики — равные колонки с подписью сверху и разделителем между ними:
   так значения не сливаются друг с другом и не липнут к краю карточки. */
.stat-metric {
    flex: 1 1 0;
    min-width: 0;
    text-align: center;
}

.stat-metric + .stat-metric {
    border-left: 1px solid #e9ecef;
    margin-left: 0.5rem;
    padding-left: 0.5rem;
}

.stat-metric-label {
    /* Подпись сверху фиксированной высоты: одна-две строки — но цифры во всех
       колонках и карточках стоят на одной линии. */
    display: flex;
    align-items: flex-end;
    justify-content: center;
    min-height: 2.2em;
    font-size: 0.66rem;
    letter-spacing: 0.2px;
    line-height: 1.15;
    text-align: center;
    text-transform: uppercase;
    color: #6c757d;
    margin-bottom: 0.35rem;
    overflow-wrap: normal;
    word-break: keep-all;
    hyphens: none;
}

.stat-metric-value {
    font-size: 1.35rem;
    font-weight: 600;
    line-height: 1.1;
    white-space: nowrap;
}

/* На телефоне колонки метрик узкие: чуть уменьшаем цифру, чтобы ничего не вылезало. */
@media (max-width: 575.98px) {
    .stat-metric-value {
        font-size: 1.15rem;
    }

    .stat-metric-label {
        font-size: 0.62rem;
    }
}

.section-card-knowledge {
    border-top: 3px solid #0d6efd;
}

.section-card-accesses {
    border-top: 3px solid #fd7e14;
}

.section-card-projects {
    border-top: 3px solid #198754;
}

/* Логотип */
.logo-link {
    transition: opacity 0.15s ease;
}

.logo-link:hover {
    opacity: 0.8;
}

.logo-img {
    display: block;
    width: auto;
    max-width: 100%;
}

/* Favicon не влияет на верстку */

.navbar .logo-img {
    max-height: 36px;
}
/* Главная: подсказка «С чего начать» */
.onboarding-card {
    border: 1px solid #e9ecef;
    border-left: 4px solid #0d6efd;
}

.onboarding-step {
    border: 1px solid #e9ecef;
    border-radius: 0.5rem;
    background: #fff;
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

.onboarding-step.is-done {
    background: #f6fbf7;
    border-color: #badbcc;
}

.onboarding-step.is-done .onboarding-title {
    color: #6c757d;
    text-decoration: line-through;
}

.onboarding-num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 50%;
    background: #0d6efd;
    color: #fff;
    font-size: 0.875rem;
    font-weight: 600;
}

.onboarding-step.is-done .onboarding-num {
    background: #198754;
}

/* Название задачи в списке показываем целиком, даже если оно длинное. */
.task-title {
    white-space: normal;
    overflow-wrap: anywhere;
}

/* Статус: сам бейдж — кнопка открытия списка (без «списка + бейджа» рядом). */
.status-badge-toggle {
    border: 0;
    font-weight: 500;
    cursor: pointer;
}

.status-badge-toggle::after {
    margin-left: .35rem;
    vertical-align: .1em;
}

/* Дашборд проектов: на телефоне таблица разворачивается в читаемые карточки,
   чтобы состояние, срок и задачи были видны без горизонтальной прокрутки. */
@media (max-width: 991.98px) {
    .dashboard-table,
    .dashboard-table tbody,
    .dashboard-table tr,
    .dashboard-table td {
        display: block;
        width: auto;
    }

    .dashboard-table thead {
        display: none;
    }

    .dashboard-table tr.dashboard-group td {
        border: 0;
        padding: 0.5rem 0.75rem;
        border-radius: 0.25rem;
    }

    .dashboard-table tr.dashboard-project {
        position: relative;
        padding: 0.6rem 0.75rem 0.6rem 2.4rem;
        border-bottom: 1px solid var(--bs-border-color, #dee2e6);
    }

    .dashboard-table td {
        border: 0;
        padding: 0 0 0.15rem 0;
        text-align: left !important;   /* в карточке подписи и значения читаются слева */
    }

    /* подпись колонки — только в мобильной раскладке */
    .dashboard-table tr.dashboard-project td[data-label]::before {
        content: attr(data-label);
        color: var(--bs-secondary-color, #6c757d);
        font-size: 0.78rem;
        margin-right: 0.25rem;
    }

    /* срок и исполнители на телефоне тоже нужны, хотя в таблице они скрыты */
    .dashboard-table td.d-none.d-lg-table-cell,
    .dashboard-table td.d-none.d-xxl-table-cell {
        display: block !important;
    }

    .dashboard-table tr.dashboard-project td.dashboard-cell-toggle {
        position: absolute;
        left: 0.5rem;
        top: 0.5rem;
        width: auto;
        padding: 0;
    }

    .dashboard-table tr.dashboard-tasks td {
        padding: 0.5rem 0.75rem;
    }

    /* строки, скрытые логикой (свёрнутые группы и задачи), остаются скрытыми */
    .dashboard-table tr.d-none {
        display: none !important;
    }
}

/* Аватарки пользователей: фото профиля из Битрикс24, иначе инициалы в цветном круге */
.user-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    max-width: 100%;
    vertical-align: middle;
}

.user-chip-name {
    white-space: normal;
    overflow-wrap: anywhere;
}

.user-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    border-radius: 50%;
    overflow: hidden;
    background-color: #ced4da;
    color: #fff;
    font-weight: 600;
    line-height: 1;
    user-select: none;
}

.user-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.user-avatar-md { width: 1.75rem; height: 1.75rem; font-size: 0.7rem; }
.user-avatar-sm { width: 1.35rem; height: 1.35rem; font-size: 0.6rem; }

.user-avatar-empty[data-hue="0"] { background-color: #0d6efd; }
.user-avatar-empty[data-hue="1"] { background-color: #6f42c1; }
.user-avatar-empty[data-hue="2"] { background-color: #d63384; }
.user-avatar-empty[data-hue="3"] { background-color: #fd7e14; }
.user-avatar-empty[data-hue="4"] { background-color: #198754; }
.user-avatar-empty[data-hue="5"] { background-color: #20c997; }

.user-chip-role {
    color: var(--bs-secondary-color, #6c757d);
    font-size: 0.78rem;
}

/* Стопка аватарок: колонка «Исполнители» на дашборде */
.avatar-stack {
    display: inline-flex;
    align-items: center;
}

.avatar-stack .user-avatar {
    margin-left: -0.35rem;
    box-shadow: 0 0 0 2px #fff;
}

.avatar-stack .user-avatar:first-child {
    margin-left: 0;
}

.avatar-stack-more {
    margin-left: 0.35rem;
    color: var(--bs-secondary-color, #6c757d);
    font-size: 0.78rem;
}

/* Команда проекта в карточке */
.team-role {
    color: var(--bs-secondary-color, #6c757d);
    font-size: 0.78rem;
    margin-bottom: 0.25rem;
}

/* Дашборд: колонка прогресса задач — чтобы полоса и «N из M» читались */
.dashboard-progress {
    width: 6.5rem;
    min-width: 6.5rem;
}

/* ===========================================================================
   Блок «Установите DocLibs на телефон»
   =========================================================================== */

.install-app-icon {
    border-radius: 18px;
    box-shadow: 0 6px 18px rgba(10, 90, 255, .22);
    flex: 0 0 auto;
}


/* ---------- Вкладки в карточке проекта ----------
   На узких экранах вкладки прокручиваются вбок одной строкой,
   чтобы не разъезжаться и не переноситься по одной букве. */
.project-tabs {
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
}
.project-tabs .nav-link {
    white-space: nowrap;
    padding: .5rem .95rem;
    font-size: .95rem;
    color: #495057;
}
.project-tabs .nav-link.active {
    font-weight: 600;
}
.project-tabs::-webkit-scrollbar { height: 4px; }
.project-tabs::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, .18); border-radius: 2px; }

@media (max-width: 575.98px) {
    .project-tabs .nav-link { padding: .45rem .7rem; font-size: .875rem; }
    .tab-content > .tab-pane > .row { --bs-gutter-y: 1rem; }
}


/* ---------- Список задач в карточке проекта ----------
   Задач бывает много, поэтому фильтр по статусу и поиск стоят над списком,
   часы выделены, а ссылка в портал занимает одну стрелку. */
.task-filters .task-filter {
    border-radius: 999px;
    padding: .25rem .7rem;
}
.task-filters .task-filter .badge {
    font-weight: 600;
    opacity: .85;
}
.task-filters .task-search {
    max-width: 240px;
}
.task-hours {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    padding: .08rem .4rem;
    border: 1px solid #dbe0f7;
    border-radius: .375rem;
    background: #f3f5fd;
    color: #3c4670;
    font-size: .8125rem;
    font-weight: 500;
    white-space: nowrap;
}
.task-portal-link {
    color: #97a1b0;
    font-size: 1.1rem;
    line-height: 1;
    text-decoration: none;
}
.task-portal-link:hover,
.task-portal-link:focus {
    color: #0d6efd;
}
@media (max-width: 575.98px) {
    .task-filters .task-search {
        max-width: none;
        flex: 1 1 100%;
    }
}


/* ---------- Таблица задач в карточке проекта ----------
   Три колонки: задача и ответственный, время, статус. Время и статус стоят
   на своих местах, поэтому взгляд находит их сразу, без поиска по строке. */
.task-table-wrap {
    background: #fff;
    border: 1px solid #e9ecef;
    border-radius: .5rem;
    overflow: hidden;
}
.task-table thead th {
    padding: .55rem .75rem;
    background: #f8f9fa;
    border-bottom: 1px solid #e9ecef;
    font-size: .82rem;
    font-weight: 500;
    color: #8a9199;
    white-space: nowrap;
}
.task-table tbody td {
    padding: .6rem .75rem;
    vertical-align: middle;
}
.task-table .task-col-hours { width: 120px; }
.task-table .task-col-status { width: 170px; }
.task-table .task-cell-hours,
.task-table .task-cell-status { white-space: nowrap; }
.task-table .task-title-line {
    display: flex;
    align-items: baseline;
    gap: .4rem;
}
.task-table .task-title-link:hover .task-title { text-decoration: underline; }
.task-table .task-meta { margin-top: .15rem; font-size: .8rem; line-height: 1.2; }
/* Флаги задачи: видно, что мешает поставить её в Битрикс24. */
.task-table .task-flag {
    font-size: .7rem;
    font-weight: 400;
    padding: .05rem .35rem;
    vertical-align: middle;
}
.task-table .task-flag-push { color: #8a6d3b; background: #fff3cd; border: 1px solid #ffe69c; }
.task-table .task-flag-deadline { color: #6c757d; background: #f1f3f5; border: 1px solid #dee2e6; }
.task-table .task-finished { margin-top: .2rem; color: #6c757d; font-size: .75rem; }

/* Подсказка-вопросик: пояснения к полям по наведению или тапу,
   чтобы таблицы оставались читаемыми без простыней текста. */
.hint {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.05rem;
    height: 1.05rem;
    border-radius: 50%;
    border: 1px solid #c3c9d1;
    color: #6b7280;
    font-size: .7rem;
    line-height: 1;
    cursor: help;
    position: relative;
    flex: 0 0 auto;
    vertical-align: middle;
}
.hint::after {
    content: attr(data-tip);
    position: absolute;
    left: 50%;
    bottom: 145%;
    transform: translateX(-50%);
    z-index: 40;
    width: max-content;
    max-width: 300px;
    background: #1f2937;
    color: #fff;
    padding: .45rem .6rem;
    border-radius: .35rem;
    font-size: .72rem;
    line-height: 1.35;
    text-align: left;
    white-space: pre-line;
    display: none;
    pointer-events: none;
    box-shadow: 0 6px 18px rgba(15, 23, 42, .22);
}
.hint-right::after { left: auto; right: 0; transform: none; }
/* Вниз — для подсказок в заголовках таблиц: выше подсказку обрезает обёртка таблицы */
.hint-down::after { top: 145%; bottom: auto; }

/* На телефоне подсказка показывается панелью поверх содержимого:
   position: fixed не расширяет страницу и не режет текст за краем экрана. */
@media (max-width: 767.98px) {
    .hint::after,
    .hint-right::after,
    .hint-left::after {
        position: fixed;
        left: .75rem;
        right: .75rem;
        top: 4.75rem;
        bottom: auto;
        width: auto;
        max-width: none;
        transform: none;
        z-index: 1080;
    }
}
.hint-left::after  { left: auto; left: 0; transform: none; }
.hint:hover::after,
.hint:focus::after { display: block; }

/* Заметка к строке сметы: в свёрнутом виде не мешает читать таблицу */
.row-note > summary { cursor: pointer; color: #8a9199; font-size: .72rem; list-style: none; }
.row-note > summary::-webkit-details-marker { display: none; }
.row-note[open] > summary { color: #1a6fa8; }
.row-note textarea { margin-top: .25rem; font-size: .78rem; }

/* Коридоры маржи в смете: отлично → из ряда вон */
.margin-great    { color: #0f7b3f; font-weight: 600; }
.margin-ok       { color: #1a6fa8; font-weight: 600; }
.margin-low      { color: #9a6b00; font-weight: 600; }
.margin-critical { color: #c2571a; font-weight: 700; }
.margin-loss     { color: #b3261e; font-weight: 700; }
.margin-unknown  { color: #8a9199; }

/* Кнопки действий в строке таблицы: одинаковые квадраты.
   Без этого flex растягивает кнопку с самой высокой/широкой иконкой
   (например ✏️ против ⏸ и 🗑), и они выглядят разного размера. */
.row-actions {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem;
    justify-content: flex-end;
    align-items: center;
}
.row-actions form { display: inline-flex; margin: 0; }

/* Кнопка-иконка: одинаковый квадрат независимо от того, что нарисовано внутри
   (✏️, 🏷️, ⏸, 🗑 рисуются разной ширины и высоты). */
.btn-icon {
    width: 1.75rem;
    height: 1.75rem;
    padding: 0 !important;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: .85rem;
    line-height: 1;
}

/* Широкие таблицы с полями (смета, прайс): вид подбирается так, чтобы
   горизонтальной прокрутки не было.
   - до 992 px бокового меню нет — места хватает на таблицу;
   - 992–1199 px меню съедает ~240 px, колонки не влезают — карточки;
   - от 1200 px — таблица с фиксированными колонками;
   - меньше 768 px — карточки, подпись колонки над значением.
   Подписи колонок берутся из data-label на td. */
.stack-table { min-width: 0; width: 100%; }

@media (min-width: 768px) and (max-width: 991.98px), (min-width: 1200px) {
    .stack-table { table-layout: fixed; }
    .stack-table td, .stack-table th { overflow-wrap: break-word; }
}

@media (max-width: 767.98px), (min-width: 992px) and (max-width: 1199.98px) {
    .stack-table thead { display: none; }
    .stack-table,
    .stack-table tbody,
    .stack-table tr,
    .stack-table td,
    .stack-table tfoot { display: block; width: 100%; }
    .stack-table tbody tr {
        padding: .6rem .75rem .75rem;
        border-bottom: 1px solid #eef0f2;
    }
    .stack-table tbody tr:last-child { border-bottom: none; }
    .stack-table tbody td {
        padding: .28rem 0;
        border: none;
        text-align: left !important;
    }
    .stack-table tbody td[data-label]::before,
    .stack-table tfoot td[data-label]::before {
        content: attr(data-label);
        display: block;
        font-size: .68rem;
        text-transform: uppercase;
        letter-spacing: .3px;
        color: #8a9199;
        margin-bottom: .15rem;
    }
    .stack-table tfoot td { padding: .25rem 0; border: none; text-align: left !important; }
    .stack-table .form-control,
    .stack-table .form-select { max-width: 100%; }
    .stack-table textarea { min-width: 0 !important; }
}

/* В карточном режиме на 992–1199 px карточка компактная:
   подпись колонки и значение — в одну строку. */
@media (min-width: 992px) and (max-width: 1199.98px) {
    .stack-table tbody tr {
        padding: .5rem .75rem .6rem;
        margin-bottom: .5rem;
        border: 1px solid #eaedf0;
        border-radius: .5rem;
    }
    .stack-table tbody tr:last-child { border-bottom: 1px solid #eaedf0; margin-bottom: 0; }
    .stack-table tbody td {
        display: grid;
        grid-template-columns: 120px minmax(0, 1fr);
        align-items: baseline;
        gap: .5rem;
        padding: .18rem 0;
    }
    .stack-table tbody td[data-label]::before { margin-bottom: 0; }
    .stack-table tbody td:first-child {
        grid-template-columns: minmax(0, 1fr);
        padding-bottom: .35rem;
    }
    .stack-table tbody td:first-child::before { display: none; }
}


/* На телефоне таблица разбирается в карточки: три колонки в узкий экран не влезают */
@media (max-width: 767.98px) {
    .task-table thead { display: none; }
    .task-table,
    .task-table tbody,
    .task-table tr,
    .task-table td { display: block; width: 100%; }
    .task-table tbody tr.task-row {
        padding: .7rem .75rem;
        border-bottom: 1px solid #eef0f2;
    }
    .task-table tbody tr.task-row:last-child { border-bottom: none; }
    .task-table tbody td { padding: 0; border: none; }
    .task-table .task-cell-hours,
    .task-table .task-cell-status {
        display: inline-block;
        width: auto;
        margin-top: .45rem;
        margin-right: .5rem;
    }
}


/* ---------------------------------------------------------------------------
   Единая подача данных: подпись поля — мелкая и серая, значение — тёмное и чуть
   крупнее, между полями воздух. Введено 25.09.2026 по замечанию владельца:
   одинаковые по виду подписи и значения сливались в «кашу» и плохо читались.
   Контраст умеренный — без жирного текста и цветных акцентов.
   --------------------------------------------------------------------------- */
.dl-fields { row-gap: .95rem; }

.dl-field-label {
    font-size: 12px;
    line-height: 1.25;
    letter-spacing: .01em;
    color: #a3a9b1;
    margin-bottom: .2rem;
}

.dl-field-value {
    font-size: 15px;
    line-height: 1.5;
    color: #424956;
    overflow-wrap: anywhere;
}

.dl-field-value.is-empty { color: #a3a9b1; }
.dl-field-value code { font-size: .85rem; }

/* Подписи в формах выглядят так же, как подписи в режиме чтения: страница
   не «прыгает» при переходе «Редактировать» → «Сохранить». */
.form-label {
    font-size: 12px;
    line-height: 1.25;
    color: #a3a9b1;
    font-weight: 500;
    margin-bottom: .2rem;
}

/* Значения в полях ввода — того же цвета, что значения в режиме чтения. */
.form-control,
.form-select {
    font-size: 15px;
    color: #424956;
}

/* Форма входа и восстановления пароля: подпись — единственный ориентир у поля,
   рядом нет значения для сравнения, поэтому здесь она темнее, чем в карточках данных. */
.dl-auth .form-label { color: #6b7280; }

/* Списки параметров (карточки проектов и задач): подпись — как у полей, значение — обычным
   весом. У Bootstrap `dt` жирный, из-за этого подписи «перебивали» значения. */
dt.dl-field-label { font-weight: 400; }
dd.dl-field-value { margin-bottom: .35rem; }

/* ---------------------------------------------------------------------------
   Смета: страница читается значениями, поля открываются кнопкой «Редактировать».
   В режиме чтения поля выглядят как текст (без рамок и стрелок) и не принимают
   клики — правка случайно не включится. В режиме правки значения-текст скрыты,
   а ячейки выровнены по верху: иначе поля в одной строке «прыгают» по высоте.
   --------------------------------------------------------------------------- */
.estimate-card.is-read .form-control,
.estimate-card.is-read .form-select {
    border-color: transparent;
    background-color: transparent;
    padding-left: 0;
    padding-right: 0;
    color: #424956;
    pointer-events: none;
    box-shadow: none;
    appearance: none;
    -webkit-appearance: none;
}

/* В режиме чтения от полей правки не остаётся следов: ни стрелок порядка, ни уголка
   растягивания у текстовых полей, ни нативного вида списков — даже если поле не обёрнуто
   в estimate-edit-only. Владелец: артефакты редактируемых полей в режиме чтения недопустимы. */
.estimate-card.is-read textarea.form-control { resize: none !important; }
.estimate-card.is-read .est-move,
.estimate-card.is-read .est-move-btn,
.estimate-card.is-read .block-rename,
.estimate-card.is-read .row-note { display: none !important; }
.estimate-card.is-edit textarea.form-control { resize: vertical; }

/* Работа в режиме чтения — текст (переносы строк как в исходных данных), а не поле ввода. */
.estimate-work-text { display: block; white-space: pre-line; }

/* Форма добавления строки работает всегда: это не правка существующих данных, а способ их
   внести. Раньше её поля тоже гасились режимом чтения — форма была видна, но не кликалась. */
.estimate-card.is-read form[data-estimate-add] .form-control,
.estimate-card.is-read form[data-estimate-add] .form-select {
    border-color: var(--bs-border-color);
    background-color: var(--bs-body-bg);
    padding-left: .5rem;
    padding-right: .5rem;
    pointer-events: auto;
    box-shadow: none;
}
.estimate-card.is-read .form-check-input { pointer-events: none; }

/* ---------------------------------------------------------------------------
   Смета: порядок строк и разделов меняется стрелками (кнопки с formaction) —
   надёжнее перетаскивания мышью. Стили общие: карточка сметы в реестре и
   вкладка сметы в проекте используют один и тот же блок таблицы.
   --------------------------------------------------------------------------- */
.est-move { display: inline-flex; flex-direction: column; gap: .1rem; }
.est-move-btn {
    border: 1px solid #d0d5dd;
    background: #fff;
    color: #475467;
    border-radius: .25rem;
    line-height: 1;
    font-size: .7rem;
    padding: .12rem .32rem;
    cursor: pointer;
}
.est-move-btn:hover:not(:disabled) { border-color: #0d6efd; color: #0d6efd; }
.est-move-btn:disabled { opacity: .35; cursor: default; }
/* Владелец: раздел сметы выделяем тем же жёлтым, что и тип проекта в списке проектов
   (Bootstrap table-warning, #fff3cd) — так разделы видно с первого взгляда.
   Фон задаём и ячейке строки: Bootstrap красит ячейки в цвет фона страницы,
   и фон строки под ними не виден — оставалась узкая жёлтая полоска. */
.estimate-block { background: #fff3cd; }
.estimate-block > td { background-color: #fff3cd; border-top: 1px solid #ffe69c; border-bottom: 1px solid #ffe69c; }
.estimate-block .est-move { flex-direction: row; align-items: center; }
.estimate-order-hint { font-size: .78rem; color: #667085; }
.estimate-card.is-read .estimate-edit-only { display: none !important; }
.estimate-card.is-edit .estimate-read-only { display: none !important; }

.estimate-card.is-edit td { vertical-align: top !important; }
.estimate-card.is-edit .form-control,
.estimate-card.is-edit .form-select { margin-bottom: .25rem; }

/* В режиме чтения значения идут от верхней линии строки — так они выстроены в линию,
   а не «прыгают» по вертикали вслед за высотой названия работы. */
.estimate-card.is-read td { vertical-align: top !important; }
.estimate-card.is-read .form-select { text-overflow: ellipsis; overflow: hidden; }
.estimate-card.is-read .table > :not(caption) > * > * { padding-top: .45rem; }

/* Смета: таблица занимает всю ширину блока. Раньше колонки были заданы в пикселях
   (260+150+66+80+140+165+150 = 1011px), поэтому на широком экране справа оставалось
   пустое место. Теперь ширины — в процентах от блока, сумма ровно 100%.
   Колонка «Кол-во» убрана (множитель нигде не работал), колонка «В работу» — только
   у проектной сметы; в самостоятельной вместо неё узкая колонка с кнопкой «✕». */
@media (min-width: 1200px) {
    .estimate-card .stack-table .est-col-work      { width: 30%; }
    .estimate-card .stack-table .est-col-role      { width: 15%; }
    .estimate-card .stack-table .est-col-hours     { width: 9%; }
    .estimate-card .stack-table .est-col-price     { width: 14%; }
    .estimate-card .stack-table .est-col-cost      { width: 19%; }
    .estimate-card .stack-table .est-col-work-flag { width: 13%; }
    .estimate-card .stack-table .est-col-row-actions { width: 3rem; }
    /* Самостоятельная смета: колонки «В работу» нет, вместо неё узкая колонка с кнопкой «✕».
       Сумма процентов — ровно 100: иначе браузер отдаёт остаток последней колонке, и справа
       появляется широкая пустая полоса (владелец: «таблица не на всю ширину»). */
    .estimate-card .stack-table.est-table-standalone .est-col-work  { width: 34%; }
    .estimate-card .stack-table.est-table-standalone .est-col-role  { width: 17%; }
    .estimate-card .stack-table.est-table-standalone .est-col-hours { width: 10%; }
    .estimate-card .stack-table.est-table-standalone .est-col-price { width: 15%; }
    .estimate-card .stack-table.est-table-standalone .est-col-cost  { width: 20%; }
    .estimate-card .stack-table.est-table-standalone .est-col-row-actions { width: 4%; }
}

.estimate-card > .card-body { width: 100%; }
.estimate-card .table-responsive { width: 100%; }
.estimate-card .stack-table { width: 100%; }

/* В режиме чтения таблица сметы занимает всю ширину блока, поэтому горизонтальная
   прокрутка не нужна: убираем обрезку — раньше overflow у обёртки резал всплывающие
   подсказки «?» (пузырь выходил за границу обёртки и обрезался). */
@media (min-width: 1200px) {
    .estimate-card .table-responsive { overflow: visible; }
}

.estimate-card .hint { flex: 0 0 auto; }
.estimate-card .hint { white-space: nowrap; }

/* Пустое значение внутри блока значения (карточки доступов): светло-серым, как «не заполнено». */
.dl-field-value .is-empty { color: #a3a9b1; }

/* Числовые колонки таблиц: суммы и часы не должны переноситься по разрядам
   («-41 708» превращалось в «-41» + «708»). */
.table td.text-end { white-space: nowrap; }

/* Список приложений: в первой колонке название и путь к коду, а все бейджи
   («Для себя», каркас, состояние) собраны в колонке «Состояние» — так они не отбирают ширину
   у соседних колонок и не «прыгают» по строкам при длинных названиях. Название переносится:
   длинные названия больше не растягивают таблицу до горизонтальной прокрутки. */
.app-name { white-space: normal; overflow-wrap: anywhere; }
.app-state-badges {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .25rem;
    max-width: 22rem;
}

/* Заявки поддержки: компактная таблица, чтобы укладывалась в карточку без обрезки. */
.desk-table th,
.desk-table td { padding: .45rem .5rem; }
.desk-table td:first-child { min-width: 240px; }

/* ===========================================================================
   Матрица прав (Пользователи → Права доступа)
   =========================================================================== */

/* Прокрутка — внутри карточки: шапка с разделами и колонка сотрудника закреплены,
   страница при этом не «съезжает» и горизонтальной полосы у страницы не появляется. */
.perm-matrix-wrap {
    max-height: calc(100vh - 270px);
    overflow: auto;
}

.perm-matrix thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background: #fff;
    vertical-align: bottom;
    border-bottom: 1px solid #dee2e6;
}

.perm-matrix th,
.perm-matrix td {
    padding: .28rem .25rem;
}

.perm-matrix th.perm-user-col,
.perm-matrix td.perm-user-col {
    position: sticky;
    left: 0;
    z-index: 3;
    background: #fff;
    min-width: 10rem;
    box-shadow: 1px 0 0 #e9ecef;
}

.perm-matrix thead th.perm-user-col {
    z-index: 4;
}

.perm-col {
    min-width: 4.7rem;
}

.perm-col-icon {
    display: block;
    font-size: 1rem;
    line-height: 1.1;
}

.perm-col-title {
    display: block;
    font-size: .72rem;
    font-weight: 500;
    color: #6b7280;
    line-height: 1.15;
}

/* Клетка: цветной уровень, клик — следующий */
.perm-cell {
    display: inline-block;
    min-width: 4rem;
    padding: .18rem .35rem;
    border: 1px solid transparent;
    border-radius: .35rem;
    font-size: .72rem;
    line-height: 1.25;
    background: #f1f3f5;
    color: #868e96;
    cursor: pointer;
}

button.perm-cell:hover {
    border-color: #cbd0d6;
}

.perm-cell.perm-none { background: #f1f3f5; color: #868e96; }
.perm-cell.perm-read { background: #e7f1ff; color: #0d6efd; }
.perm-cell.perm-edit { background: #e6f4ea; color: #198754; font-weight: 600; }
.perm-cell.perm-full { background: #eef0f3; color: #6b7280; cursor: default; }
.perm-cell.perm-static { cursor: default; }

/* Правка, ещё не сохранённая: обводим клетку, чтобы видеть, что уйдёт на сервер */
.perm-matrix td.perm-changed .perm-cell {
    box-shadow: 0 0 0 2px #ffc107;
}

/* Отключённые сотрудники — в конце списка и приглушены */
.perm-row-off td {
    opacity: .6;
}

.perm-legend {
    display: inline-block;
    padding: 0 .35rem;
    border-radius: .25rem;
    font-size: .72rem;
}

/* ---------------------------------------------------------------------------
   Выбор варианта предложения (внутренние формы и карточка КП):
   короткие кнопки в один ряд вместо «прыгающих» вкладок с длинными названиями.
   --------------------------------------------------------------------------- */
.kp-editor-tabs {
    display: flex;
    flex-wrap: nowrap;
    gap: .5rem;
    overflow-x: auto;
    padding-bottom: .25rem;
}
.kp-variant-tab {
    flex: 0 0 auto;
    padding: .4rem .8rem;
    border: 1px solid #dee2e6;
    border-radius: .5rem;
    background: #fff;
    color: #2159f5;
    text-align: center;
    white-space: nowrap;
    line-height: 1.25;
    cursor: pointer;
}
.kp-variant-tab:hover { border-color: #2159f5; }
.kp-variant-tab.is-active { border-color: #2159f5; background: #2159f5; color: #fff; }
.kp-variant-name { display: block; font-weight: 600; }
.kp-variant-sum { display: block; font-size: .8125rem; opacity: .85; }
.kp-variant-hidden { display: block; font-size: .75rem; opacity: .75; }
.kp-variant-panel { border-top: 1px solid #e9ecef; }
