/*  
    References:

        ms:             margin left.
        me:             margin right.
        mx:             margin left and right.
        my:             margin top and bottom.

        mb-lg-          applied only in lg devices (992px).

        col-:           smallest devices.
        col-sm-         576px.
        col-md-         768px.
        col-lg          992px.
        col-xl          1200px.
        col-xxl         1400px.
        common pcs      1920x1080.
*/

/* 
    Leanmote Colors 
*/

:root {

    --lm-primary-dark:      #1C2E62;
    --lm-secondary-dark:    #4F7AB0;
    --lm-primary-light:     #419FFF;
    --lm-white:             #FFFFFF;
    --lm-light-grey:        #E0E0E0;
    --lm-medium-grey:       #999999;
    --lm-strong-gray:       #666666;
    --lm-black:             #000000;
    --lm-red:               #FF3366;
    --lm-green:             #40D390;
    --lm-yellow:            #ECB22E;
    --lm-violet:            #C91EEB;
    --gray-background:      #F9F9F9;

}

/*  
    Leanmote Styles 
*/

.lm-bg-primary-dark {
    background-color:       var(--lm-primary-dark)!important;
}

/* -------------------------------------------------------------------------
   White-label overrides

   The `lm-white-label-active` class is added to <body> by the app layout
   whenever the org has `white_label_enabled = 1`. When present, the brand
   variables `--lm-brand-primary` and `--lm-brand-secondary` are injected by
   layouts/app/components/head.php and these rules pick them up. Without
   the class (default Leanmote orgs), none of these rules fire — sidebar
   and links keep their original Metronic + Leanmote styling.
   ------------------------------------------------------------------------- */

/* Sidebar background follows the org's primary color. */
body.lm-white-label-active .app-sidebar.lm-bg-primary-dark {
    background-color:       var(--lm-brand-primary)!important;
}

/* Inactive sidebar menu link text follows the org's secondary color
   (defaults to Leanmote's light grey — i.e. the muted text color used on
   the dark sidebar today). Active items keep their bright/white state so
   the current page stays distinguishable. */
body.lm-white-label-active .app-sidebar .menu-item .menu-link:not(.active) .menu-title,
body.lm-white-label-active .app-sidebar .menu-item .menu-link:not(.active) .menu-arrow,
body.lm-white-label-active .app-sidebar .menu-item .menu-link:not(.active) .menu-icon i {
    color:                  var(--lm-brand-secondary)!important;
}

/* Active sidebar item background follows a slightly darker shade of the
   brand primary. `color-mix` keeps the relationship intrinsic — any picked
   primary produces a usable active state without needing a second color
   from the user. 70%/30% mix matches the depth used by the Primary Target
   banner so the platform feels visually consistent. */
body.lm-white-label-active .app-sidebar .menu-item .menu-link.active {
    background-color:       color-mix(in srgb, var(--lm-brand-primary) 70%, black)!important;
}

/* Primary CTA buttons follow the org's primary color. Same color across
   base/hover/focus/active states; `opacity: 0.85` on hover provides
   color-agnostic visual feedback (a `filter: brightness()` derivation
   produces no visible change at near-black or near-white brand colors). */
body.lm-white-label-active .btn-primary,
body.lm-white-label-active .btn-primary:focus,
body.lm-white-label-active .btn-primary:active,
body.lm-white-label-active .btn-primary:not(:disabled):not(.disabled):active {
    background-color:       var(--lm-brand-primary)!important;
    border-color:           var(--lm-brand-primary)!important;
}

body.lm-white-label-active .btn-primary:hover:not(:disabled):not(.disabled) {
    background-color:       var(--lm-brand-primary)!important;
    border-color:           var(--lm-brand-primary)!important;
    opacity:                0.85;
}

/* Primary Target banner on /strategic-overview. Its dark-blue gradient is
   inlined in the view (style="background: linear-gradient(135deg, #1b2559…)")
   so the override has to use `!important` to beat the inline rule. The
   `color-mix` darker stop preserves the depth of the original gradient
   regardless of the brand primary chosen.

   The progress bar inside the banner reads from `--bs-primary` by default
   (Metronic blue), which would clash with the now-brand-colored banner
   background. A translucent white fill keeps it visible on any
   sufficiently dark brand primary — light-primary orgs already get a
   contrast warning on the settings form. */
body.lm-white-label-active #primary-target-banner {
    background:             linear-gradient(
                                135deg,
                                var(--lm-brand-primary) 0%,
                                color-mix(in srgb, var(--lm-brand-primary) 70%, black) 100%
                            )!important;
}

body.lm-white-label-active #primary-target-banner .progress-bar {
    background-color:       rgba(255, 255, 255, 0.6)!important;
}

/* AHOE command-center banner (AI Governance → AHOE). Same treatment as the
   Primary Target banner: its 3-stop navy gradient is inlined by the JS that
   renders the banner (public/js/ai-tools/general.js), so the override needs
   `!important` to beat the inline rule. The lighter stops are derived from
   the brand primary via `color-mix` so the gradient keeps its depth for any
   picked color. The white text/circles on top read from `--lm-brand-primary`
   directly (inline vars with a navy fallback), so they follow along without a
   rule here. Default (non-white-label) orgs keep the inlined navy gradient. */
body.lm-white-label-active .ahoe-cmd-banner {
    background-image:       linear-gradient(
                                120deg,
                                var(--lm-brand-primary) 0%,
                                color-mix(in srgb, var(--lm-brand-primary) 80%, white) 55%,
                                color-mix(in srgb, var(--lm-brand-primary) 62%, white) 100%
                            )!important;
}

/* -------------------------------------------------------------------------
   RD-2211: public / shared-view chrome follows the SHARING org's primary.
   The public view now renders with the owner org's white-label (see
   PublicViewController::index), so its lead-gen CTA card, buttons, tab hover
   and the header "Sign in" — which shipped with hardcoded Leanmote-navy /
   celeste values — must track `--lm-brand-primary` too. Base (default-org)
   styling stays in public-view-sidebar.php and is untouched for non-WL orgs.
   ------------------------------------------------------------------------- */

/* "Improve your team's metrics" CTA card: a soft, slightly darker shade of
   the primary so it reads as a subtle sunk panel on the primary sidebar,
   keeping white text legible. Border + icon tile are faint primary tints. */
body.lm-white-label-active .lm-public-sidebar-cta-card {
    background:             color-mix(in srgb, var(--lm-brand-primary) 68%, black)!important;
    border-color:           color-mix(in srgb, var(--lm-brand-primary) 40%, transparent)!important;
}

body.lm-white-label-active .lm-public-sidebar-cta-icon {
    background:             color-mix(in srgb, var(--lm-brand-primary) 30%, transparent)!important;
    color:                  #ffffff!important;
}

/* CTA button on the dark card: brand-tinted at rest, solid brand primary on
   hover, subtle press. Explicit transition properties (not `all`). */
body.lm-white-label-active .lm-public-sidebar-cta-card .btn-light-primary {
    background-color:       color-mix(in srgb, var(--lm-brand-primary) 20%, transparent)!important;
    color:                  #ffffff!important;
    border-color:           transparent!important;
    transition:             background-color 0.2s ease, transform 0.16s ease;
}

body.lm-white-label-active .lm-public-sidebar-cta-card .btn-light-primary:hover,
body.lm-white-label-active .lm-public-sidebar-cta-card .btn-light-primary:focus {
    background-color:       var(--lm-brand-primary)!important;
    color:                  #ffffff!important;
}

body.lm-white-label-active .lm-public-sidebar-cta-card .btn-light-primary:active {
    transform:              scale(0.97);
}

/* Header "Sign in": solid brand primary (readable on the light header),
   hover fades opacity for color-agnostic feedback (mirrors the .btn-primary
   treatment above), subtle press. */
body.lm-white-label-active .lm-public-signin {
    background-color:       var(--lm-brand-primary)!important;
    border-color:           var(--lm-brand-primary)!important;
    color:                  #ffffff!important;
    transition:             opacity 0.2s ease, transform 0.16s ease;
}

body.lm-white-label-active .lm-public-signin:hover:not(:disabled),
body.lm-white-label-active .lm-public-signin:focus {
    background-color:       var(--lm-brand-primary)!important;
    border-color:           var(--lm-brand-primary)!important;
    color:                  #ffffff!important;
    opacity:                0.85;
}

body.lm-white-label-active .lm-public-signin:active {
    transform:              scale(0.97);
}

/* Inactive tab hover follows a shade of the primary (the active tab is
   already handled by the shared .menu-link.active rule above). Slightly
   lighter than the active shade so rest -> hover -> active reads as a clear
   depth hierarchy. The transition already lives on .lm-public-sidebar-button. */
body.lm-white-label-active .lm-public-sidebar .menu-item .menu-link:not(.active):hover {
    background-color:       color-mix(in srgb, var(--lm-brand-primary) 84%, black)!important;
}

/* Line tabs (dashboard sections, drill-downs, etc.) across the whole app.
   Metronic's `.nav-line-tabs .nav-link.active` + `.text-active-primary` read
   from `--bs-primary` (Leanmote celeste). For white-label orgs the active
   text + underline (and the hover underline) should follow the brand primary
   instead. Scoped to the shared Metronic class, so every nav-line-tabs group
   on the platform is covered without touching markup. */
body.lm-white-label-active .nav-line-tabs .nav-link.active,
body.lm-white-label-active .nav-line-tabs .nav-item.show .nav-link {
    color:                  var(--lm-brand-primary)!important;
    border-bottom-color:    var(--lm-brand-primary)!important;
}

body.lm-white-label-active .nav-line-tabs .nav-link:hover:not(.disabled):not(.active),
body.lm-white-label-active .nav-line-tabs .nav-item.show .nav-link:hover {
    color:                  var(--lm-brand-primary)!important;
    border-bottom-color:    var(--lm-brand-primary)!important;
}

.app-sidebar .app-sidebar-logo {
    border-bottom:          none!important;
}

.hover-primary-lm:hover{
    color:                  var(--lm-primary-light)!important;
    border:                 1px solid var(--lm-primary-light)!important;
}

.hover-primary-lm:hover > i{
    color:                  var(--lm-primary-light)!important;
}

.medium-grey-cl{
    color:                  var(--lm-medium-grey)!important;
}

.red-cl{
    color:                  var(--lm-red)!important;
}

.green-cl{
    color:                  var(--lm-green)!important;
}

.medium-grey-badge{
    color:                  var(--lm-medium-grey)!important;
    border:                 1px solid var(--lm-medium-grey)!important;
}

.green-badge{
    color:                  var(--lm-green)!important;
    border:                 1px solid var(--lm-green)!important;
}

.red-badge{
    color:                  var(--lm-red)!important;
    border:                 1px solid var(--lm-red)!important;
}

/* RD-2055 — "[isologo] #id · repo" chip shown next to a PR name in Show Details
   tables. Layout only; color/border come from .medium-grey-badge. */
.lm-pr-chip{
    display:                inline-flex;
    align-items:            center;
    gap:                    4px;
    padding:                1px 6px;
    font-size:              0.7rem;
    font-weight:            600;
    vertical-align:         middle;
    max-width:              100%;
}
.lm-pr-chip-id{
    line-height:            1;
}
.lm-pr-chip-repo{
    line-height:            1;
    max-width:              140px;
    overflow:               hidden;
    text-overflow:          ellipsis;
    white-space:            nowrap;
}

/* RD-2055 / RD-2854 — subtitle-placement isologo strips (a row under the card
   title, which the card GROWS to fit via min-h-175px in dashboard.php).
   RD-2854 moved the Review Collaboration and Tasks Collaboration cards to a
   single strip on their section heading, so only the Meeting Impact block still
   places strips per card — its heading (#meetings-title-for) is JS-driven and
   empty by default, so there is nowhere to hang a section strip. Keep this list
   in sync with dashboard_card_isologo_placement() in
   app/Helpers/integration_logos_helper.php. */
#total-meeting-hours .lm-card-isologos,
#avg-focus-time-availability .lm-card-isologos,
#avg-meeting-duration .lm-card-isologos,
#total-meeting-cost .lm-card-isologos,
#recurrent-meetings-percentage .lm-card-isologos,
#avg-meeting-cost .lm-card-isologos,
#large-meeting-costs .lm-card-isologos,
#large-meetings-count .lm-card-isologos{
    margin-top:             0.5rem!important;
    margin-bottom:          0.25rem!important;
}

/* RD-2854 — the section-heading strip. It rides the heading's own line, so it
   costs the section no extra height; nudge it down a hair so the 16px marks sit
   on the text baseline rather than the cap line of a much larger heading. */
.lm-section-isologos{
    position:               relative;
    top:                    1px;
}

.highcharts-node {
    clip-path: circle(50% at center);
}

.hidden {
    display: none !important;
}

.detail-collapse-panel {
    margin-top: 0.75rem;
    padding: 1.25rem 0;
    border: 1px solid var(--bs-border-color, #eff2f5);
    border-radius: 0.95rem;
    background-color: #f9fbff;
}

.detail-collapse-panel > :last-child {
    margin-bottom: 0;
}

.detail-collapse-panel .detail-table {
    margin-bottom: 0;
}

.detail-collapse-panel .detail-indent-cell {
    width: 40px;
    padding-left: 0;
    padding-right: 0;
}

table.dataTable>thead .dt-ordering-asc, table.dataTable>thead .dt-ordering-desc {
    vertical-align: bottom!important;
}

#kt_project_investment_table.dataTable>thead th.sorting:before,
#kt_project_investment_table.dataTable>thead th.sorting:after,
#kt_project_investment_table.dataTable>thead th.sorting_asc:before,
#kt_project_investment_table.dataTable>thead th.sorting_asc:after,
#kt_project_investment_table.dataTable>thead th.sorting_desc:before,
#kt_project_investment_table.dataTable>thead th.sorting_desc:after,
#kt_project_investment_table.dataTable>thead th.dt-ordering-asc:before,
#kt_project_investment_table.dataTable>thead th.dt-ordering-asc:after,
#kt_project_investment_table.dataTable>thead th.dt-ordering-desc:before,
#kt_project_investment_table.dataTable>thead th.dt-ordering-desc:after,
#kt_collaborator_allocation_table.dataTable>thead th.sorting:before,
#kt_collaborator_allocation_table.dataTable>thead th.sorting:after,
#kt_collaborator_allocation_table.dataTable>thead th.sorting_asc:before,
#kt_collaborator_allocation_table.dataTable>thead th.sorting_asc:after,
#kt_collaborator_allocation_table.dataTable>thead th.sorting_desc:before,
#kt_collaborator_allocation_table.dataTable>thead th.sorting_desc:after,
#kt_collaborator_allocation_table.dataTable>thead th.dt-ordering-asc:before,
#kt_collaborator_allocation_table.dataTable>thead th.dt-ordering-asc:after,
#kt_collaborator_allocation_table.dataTable>thead th.dt-ordering-desc:before,
#kt_collaborator_allocation_table.dataTable>thead th.dt-ordering-desc:after,
#kt_team_allocation_table.dataTable>thead th.sorting:before,
#kt_team_allocation_table.dataTable>thead th.sorting:after,
#kt_team_allocation_table.dataTable>thead th.sorting_asc:before,
#kt_team_allocation_table.dataTable>thead th.sorting_asc:after,
#kt_team_allocation_table.dataTable>thead th.sorting_desc:before,
#kt_team_allocation_table.dataTable>thead th.sorting_desc:after,
#kt_team_allocation_table.dataTable>thead th.dt-ordering-asc:before,
#kt_team_allocation_table.dataTable>thead th.dt-ordering-asc:after,
#kt_team_allocation_table.dataTable>thead th.dt-ordering-desc:before,
#kt_team_allocation_table.dataTable>thead th.dt-ordering-desc:after,
#teams-table.dataTable>thead th.sorting:before,
#teams-table.dataTable>thead th.sorting:after,
#teams-table.dataTable>thead th.sorting_asc:before,
#teams-table.dataTable>thead th.sorting_asc:after,
#teams-table.dataTable>thead th.sorting_desc:before,
#teams-table.dataTable>thead th.sorting_desc:after,
#teams-table.dataTable>thead th.dt-ordering-asc:before,
#teams-table.dataTable>thead th.dt-ordering-asc:after,
#teams-table.dataTable>thead th.dt-ordering-desc:before,
#teams-table.dataTable>thead th.dt-ordering-desc:after {
    display: none !important;
}

.custom-sort-indicator {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 12px;
    color: #99a1b7;
}

.custom-sort-indicator::before {
    content: '';
    font-size: 0.8rem;
    line-height: 1;
}

.custom-sort-indicator.is-asc::before {
    content: '\25B2';
}

.custom-sort-indicator.is-desc::before {
    content: '\25BC';
}

.custom-sort-indicator.is-asc,
.custom-sort-indicator.is-desc {
    color: #5e6278;
}

th[data-sort-col] {
    cursor: pointer;
    user-select: none;
}

th[data-sort-col]:hover .custom-sort-indicator:not(.is-asc):not(.is-desc)::before {
    content: '\25B2\25BC';
    font-size: 0.55rem;
    opacity: 0.4;
}

#dashboard-main-tabs + .tab-content > .tab-pane > div > .row:last-child {
    margin-bottom: 0 !important;
}

#dashboard-main-tabs + .tab-content > #dashboard-ai-impact-tab > #ai-impact-trend-section > .d-flex.align-items-center,
#dashboard-main-tabs + .tab-content > #dashboard-ai-impact-others-tab > #ai-impact-section > .d-flex.align-items-center {
    margin-bottom: 1.5rem !important;
}

.main-dashboard-tab-pane {
    display: none;
}

.main-dashboard-tab-pane.active {
    display: block;
}

#dashboard-main-tabs + .tab-content > #dashboard-ai-impact-tab.main-dashboard-tab-pane.active,
#dashboard-main-tabs + .tab-content > #dashboard-ai-impact-tab.main-dashboard-tab-pane.show.active {
    display: block !important;
    align-items: flex-start !important;
    justify-content: flex-start !important;
}

#dashboard-main-tabs + .tab-content > #dashboard-ai-impact-tab.main-dashboard-tab-pane.active > #ai-impact-trend-section,
#dashboard-main-tabs + .tab-content > #dashboard-ai-impact-tab.main-dashboard-tab-pane.show.active > #ai-impact-trend-section {
    margin-top: 0 !important;
    padding-top: 0 !important;
}

#dashboard-main-tabs + .tab-content > #dashboard-ai-impact-tab #ai-impact-empty-state {
    margin-top: 0 !important;
}

.ai-insight-card {
    position: relative;
    padding: 1.25rem;
    border-radius: 0.85rem;
    background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
    border: 1px solid #e7ebf2;
    box-shadow: 0 14px 30px rgba(20, 24, 40, 0.08);
    overflow: hidden;
}

.ai-insight-card::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 6px;
    height: 100%;
    background: #cbd5f5;
}

.ai-insight-card .ai-insight-icon {
    width: 38px;
    height: 38px;
    border-radius: 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: #eef2ff;
    flex: 0 0 auto;
}

.ai-insight-card .ai-insight-badge {
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #1f2a44;
    background: #eef2ff;
    border-radius: 999px;
    padding: 0.15rem 0.5rem;
    white-space: nowrap;
}

.ai-insight--success::before {
    background: #3fd29f;
}

.ai-insight--success .ai-insight-icon,
.ai-insight--success .ai-insight-badge {
    background: #e8fbf3;
}

.ai-insight--neutral::before {
    background: #9aa4b2;
}

.ai-insight--neutral .ai-insight-icon,
.ai-insight--neutral .ai-insight-badge {
    background: #f0f3f7;
}

.ai-insight--opportunity::before {
    background: #f5c542;
}

.ai-insight--opportunity .ai-insight-icon,
.ai-insight--opportunity .ai-insight-badge {
    background: #fff4d6;
}

.ai-impact-metric-card {
    border: 1px solid #e7ebf2;
    border-radius: 0.85rem;
    background: linear-gradient(140deg, #ffffff 0%, #f6f8fb 100%);
    padding: 1.25rem;
    box-shadow: 0 12px 24px rgba(20, 24, 40, 0.06);
    height: 100%;
}

.ai-impact-metric-icon {
    width: 42px;
    height: 42px;
    border-radius: 12px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
}

.ai-impact-metric-value {
    font-size: 1.65rem;
    font-weight: 700;
    color: #1f2a44;
    line-height: 1.1;
}

.ai-impact-effect-row {
    padding: 0.35rem 0;
    border-bottom: 1px dashed #e7ebf2;
}

.ai-impact-effect-row:last-child {
    border-bottom: 0;
}

.ai-insight--danger::before {
    background: #ff6b6b;
}

.ai-insight--danger .ai-insight-icon,
.ai-insight--danger .ai-insight-badge {
    background: #ffe3e3;
}

/*
    Leanmote Responsive
*/

@media (min-width: 100px) {

}

@media (min-width: 576px) {  
    
} 

@media (min-width: 768px) {  

} 

@media (min-width: 992px) {  

} 

@media (min-width: 1200px) {  

}

@media (min-width: 1400px) {  

}

@media (min-width: 1750px) {

}
/* RD-2336: the status card stacks — name on top, then a single tidy row of
   controls. Stacking keeps it clean inside the narrow master-detail pane,
/* Order editor — a small number field (replaces the old 0–100 dropdown). Drag
   still reorders; this lets you type an exact position. Spinners hidden so the
#linear-step2-content .linear-group-disabled .linear-group-issue-types {
    opacity: 0.6;
}

#linear-step2-content .linear-group-disabled .linear-issue-type-card {
    pointer-events: none;
}
/* Sidebar collapse animation polish */
@media (min-width: 992px) {
    :root {
        --lm-sidebar-motion-duration: 340ms;
        --lm-sidebar-motion-ease: cubic-bezier(0.4, 0, 0.2, 1);
    }

    #kt_app_header,
    #kt_app_toolbar,
    #kt_app_main,
    #dashboard-container {
        transition: left var(--lm-sidebar-motion-duration) var(--lm-sidebar-motion-ease),
                    margin-left var(--lm-sidebar-motion-duration) var(--lm-sidebar-motion-ease);
    }

    .app-sidebar {
        overflow: visible;
        transition: width var(--lm-sidebar-motion-duration) var(--lm-sidebar-motion-ease),
                    margin-left var(--lm-sidebar-motion-duration) var(--lm-sidebar-motion-ease);
    }

    /* Los selectores `:not([data-kt-app-sidebar-collapse="on"])` de aca abajo son
       del tema, y hoy son siempre verdaderos: el boton de la barra usa `minimize`
       (RD-2620), no `collapse`, y nada en `public/` escribe ese atributo. Las
       reglas que SI pedian `="on"` se fueron con el modo, porque no podian
       coincidir con nada. Estas se quedan tal como estan a proposito: sacarles el
       `:not()` les baja la especificidad y ahi el tema puede empezar a ganarles
       una transicion que hoy pierden. */
    body:not([data-kt-app-sidebar-collapse="on"]) .app-sidebar {
        transition-delay: 70ms;
    }

    #kt_app_sidebar_toggle {
        z-index: 108;
        transition: box-shadow var(--lm-sidebar-motion-duration) var(--lm-sidebar-motion-ease),
                    background-color var(--lm-sidebar-motion-duration) var(--lm-sidebar-motion-ease),
                    border-color var(--lm-sidebar-motion-duration) var(--lm-sidebar-motion-ease),
                    left var(--lm-sidebar-motion-duration) var(--lm-sidebar-motion-ease),
                    transform var(--lm-sidebar-motion-duration) var(--lm-sidebar-motion-ease);
    }

    #kt_app_header .lm-org-title-wrap {
        transition: margin-left var(--lm-sidebar-motion-duration) var(--lm-sidebar-motion-ease);
    }

    .app-sidebar .app-sidebar-wrapper {
        opacity: 1;
        transform: translateX(0);
        will-change: opacity, transform;
    }

    body:not([data-kt-app-sidebar-collapse="on"]) .app-sidebar .app-sidebar-wrapper {
        transition: opacity 180ms linear 150ms,
                    transform var(--lm-sidebar-motion-duration) var(--lm-sidebar-motion-ease);
    }

    #kt_app_sidebar_toggle i {
        transition: transform var(--lm-sidebar-motion-duration) var(--lm-sidebar-motion-ease);
    }

    body:not([data-kt-app-sidebar-collapse="on"]) #kt_app_sidebar_toggle i {
        transform: rotateZ(180deg);
    }

    /* ── El menu se ACHICA, no desaparece ──────────────────────────────────
       El boton mandaba la barra fuera de pantalla (`collapse`), y ahi las
       vistas guardadas de cada uno desaparecian sin dejar rastro de por donde
       vuelven. Ahora usa `minimize`: queda un riel de 75px con los iconos, que
       es una salida visible en si misma.
       El resto de este modo lo dibuja el tema — logo compacto, titulos
       apagados, submenus plegados — pero SOLO cuando el body no pide
       `hoverable`, que es lo que ese atributo apagaba. Por eso se fue del
       <body> en vez de escribir esas reglas de nuevo acá.
       La flecha del boton es lo unico que quedaba colgado del modo viejo. */
    [data-kt-app-sidebar-minimize="on"] #kt_app_sidebar_toggle i {
        transform: rotateZ(0deg);
    }

    body:not([data-kt-app-sidebar-minimize="on"]) #kt_app_sidebar_toggle i {
        transform: rotateZ(180deg);
    }
}

/* ── Dashboard tab loading shimmer ───────────────────────────────────────────── */
/* translateX, not `left`: the sweep runs on the GPU instead of relaying out the tab. */
/* 360% is 180% of the tab read in units of the sweep's own box — retune it if the width below changes. */
@keyframes lm-tab-shimmer {
    0%   { transform: translateX(0); }
    100% { transform: translateX(360%); }
}

.nav-link.tab-loading {
    position: relative;
    overflow: hidden;
    /* The shimmer is what says "loading", so the label only dips one step below a loaded tab. */
    opacity: 0.9;
}

.nav-link.tab-loading::after {
    content: '';
    position: absolute;
    top: 0;
    left: -60%;
    width: 50%;
    height: 100%;
    /* 0.55 here x 0.9 parent opacity keeps the sweep at the strength it had when the label was dimmer. */
    background: linear-gradient(
        90deg,
        transparent 0%,
        rgba(255, 255, 255, 0.55) 50%,
        transparent 100%
    );
    animation: lm-tab-shimmer 1.4s ease-in-out infinite;
    pointer-events: none;
}

/* Lazy tab not opened yet: quieter than a loaded tab, but still readable — the tab's own gray is already light. */
.nav-link.tab-not-loaded {
    opacity: 0.8;
    transition: opacity 150ms ease-out;
}

/* Without the sweep there is no loading cue, so the tab rests at the weight of one not opened yet. */
@media (prefers-reduced-motion: reduce) {
    .nav-link.tab-loading {
        opacity: 0.8;
    }

    .nav-link.tab-loading::after {
        animation: none;
    }
}

.lm-share-dashboard-trigger {
    min-width: 45px;
    padding: 0;
}

.lm-share-dashboard-trigger-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    line-height: 1;
}

.lm-share-dashboard-trigger-icon i {
    font-size: 1.75rem;
    line-height: 1;
}

.lm-share-dashboard-menu .menu-link {
    color: #3f4254;
    font-weight: 600;
}

.lm-share-dashboard-menu .menu-link:hover {
    background: #f5f8fa;
}

.lm-share-dashboard-menu .share-dashboard-disabled-action {
    opacity: 0.55;
}

.lm-share-dashboard-menu .share-dashboard-disabled-action,
.lm-share-dashboard-menu .share-dashboard-disabled-action .menu-title,
.lm-share-dashboard-menu .share-dashboard-disabled-action .menu-icon {
    cursor: not-allowed;
}

.lm-share-dashboard-menu .share-dashboard-disabled-action:hover {
    background: #f5f8fa;
}

.lm-share-dashboard-dialog {
    max-width: 640px;
}

.lm-share-dashboard-modal {
    background: #ffffff;
    border: 1px solid #e4e6ef;
    border-radius: 1rem;
    box-shadow: 0 24px 60px rgba(15, 23, 42, 0.16);
}

.lm-share-dashboard-modal .modal-header {
    padding: 1.5rem 1.75rem 1rem;
    border-bottom: 1px solid #e9edf3;
}

.lm-share-dashboard-modal .modal-title {
    color: #3f4254;
    font-size: 1.35rem;
    font-weight: 700;
}

.lm-share-dashboard-close {
    color: #7e8299;
}

.lm-share-dashboard-close:hover {
    background: #f5f8fa;
    color: #3f4254;
}

.lm-share-dashboard-modal .modal-body {
    padding: 1.5rem 1.75rem;
    color: #5e6278;
}

.lm-share-dashboard-tabs {
    border-bottom: 1px solid #e9edf3;
    gap: 1.5rem;
    margin-bottom: 1.5rem;
}

.lm-share-dashboard-tabs .nav-link {
    margin: 0;
    padding: 0.75rem 0;
    color: #7e8299;
    border: 0;
    border-bottom: 2px solid transparent;
    background: transparent;
    font-size: 1rem;
    font-weight: 600;
}

.lm-share-dashboard-tabs .nav-link:hover {
    color: #3f4254;
}

.lm-share-dashboard-tabs .nav-link.active {
    color: #419fff;
    background: transparent;
    border-bottom-color: #419fff;
}

.lm-share-dashboard-tabs .lm-share-dashboard-disabled-tab {
    opacity: 0.55;
    cursor: not-allowed;
}

.lm-share-dashboard-intro {
    color: #3f4254;
    font-size: 1.25rem;
    font-weight: 600;
    line-height: 1.45;
    margin-top: 0.9rem;
    margin-bottom: 1.5rem;
}

.lm-share-dashboard-search-wrap {
    margin-bottom: 1.5rem;
}

.lm-share-dashboard-search-icon {
    top: 50%;
    left: 1rem;
    transform: translateY(-50%);
    color: #99a1b7;
    pointer-events: none;
}

.lm-share-dashboard-search-input,
.lm-share-dashboard-public-input {
    height: 48px;
    border-radius: 0.85rem;
    border: 1px solid #d8dee9;
    background: #ffffff;
    color: #3f4254;
    box-shadow: none;
}

.lm-share-dashboard-search-input {
    padding-left: 3rem !important;
}

.lm-share-dashboard-search-input::placeholder,
.lm-share-dashboard-public-input::placeholder {
    color: #99a1b7;
}

.lm-share-dashboard-search-input:focus {
    border-color: #419fff;
    background: #ffffff;
    color: #3f4254;
}

.lm-share-dashboard-note {
    display: flex;
    align-items: flex-start;
    gap: 0.85rem;
    color: #7e8299;
    font-size: 1rem;
    line-height: 1.55;
}

.lm-share-dashboard-note-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 22px;
    height: 22px;
    margin-top: 2px;
    color: #99a1b7;
}

.lm-share-dashboard-modal .separator {
    border-bottom-color: #eff2f5 !important;
}

.lm-share-dashboard-access-list {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
}

.lm-share-dashboard-avatar {
    width: 40px;
    height: 40px;
    border-radius: 999px;
    overflow: hidden;
    flex: 0 0 auto;
    background: #eef3f7;
}

.lm-share-dashboard-avatar img,
.lm-share-dashboard-avatar-fallback {
    width: 100%;
    height: 100%;
}

.lm-share-dashboard-avatar img {
    display: block;
    object-fit: cover;
}

.lm-share-dashboard-avatar-fallback {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.95rem;
    font-weight: 700;
    color: #419fff;
    background: #dcecff;
}

.lm-share-dashboard-access-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.lm-share-dashboard-access-name {
    color: #3f4254;
    font-size: 1.1rem;
    font-weight: 600;
}

.lm-share-dashboard-access-badge {
    color: #7e8299;
    font-size: 0.95rem;
    font-weight: 700;
    min-width: 100px;
    text-align: center;
}

.lm-share-dashboard-group-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 999px;
    background: #f1f5fb;
    color: #7e8aa2;
}

.lm-share-dashboard-user-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 999px;
    border: 1px solid #e4e6ef;
    background: #f5f8fa;
    color: #7e8299;
    font-size: 0.95rem;
    font-weight: 700;
    flex-shrink: 0;
}

.lm-share-dashboard-role-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    padding: 0.55rem 0.95rem;
    border-radius: 0.75rem;
    border: 1px solid #d8dee9;
    background: #f9fbff;
    color: #7e8299;
    font-weight: 600;
    cursor: pointer;
    min-width: 100px;
    font-size: 0.85rem;
    white-space: nowrap;
}

.lm-share-dashboard-role-button:hover,
.lm-share-dashboard-role-button:active,
.lm-share-dashboard-role-button:focus {
    border-color: #d8dee9 !important;
    background: #f9fbff !important;
    color: #7e8299 !important;
    box-shadow: none !important;
}

.lm-share-dashboard-role-button:disabled {
    opacity: 1;
    cursor: default;
}

.lm-share-dashboard-role-button::after {
    margin-left: 0.35rem;
    font-size: 0.65rem;
}

.lm-share-role-dropdown {
    min-width: 240px;
    border-radius: 0.75rem;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
}

.lm-share-role-dropdown .dropdown-item {
    padding: 0.75rem 1.15rem;
    font-size: 0.925rem;
    font-weight: 500;
    color: #7e8299;
}

.lm-share-role-dropdown .dropdown-item:hover,
.lm-share-role-dropdown .dropdown-item:focus {
    background-color: #f9fbff;
    color: #7e8299;
}

.lm-share-role-dropdown .dropdown-item.active,
.lm-share-role-dropdown .dropdown-item:active {
    background-color: #f1f5ff;
    color: #3baaf7;
}

.lm-share-dashboard-public-card {
    padding: 1.25rem;
    border: 1px solid #e4e6ef;
    border-radius: 1rem;
    background: #f9fbff;
}

.lm-share-dashboard-public-title {
    color: #3f4254;
    font-size: 1rem;
    font-weight: 700;
    margin-bottom: 0.3rem;
}

.lm-share-dashboard-public-copy {
    color: #7e8299;
    line-height: 1.5;
}

.lm-share-dashboard-copy-button {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    border: 1px solid #d8dee9;
    background: #ffffff;
    color: #3f4254;
}

.lm-share-dashboard-copy-button:hover,
.lm-share-dashboard-copy-button:focus,
.lm-share-dashboard-copy-button:disabled {
    border-color: #d8dee9;
    background: #ffffff;
    color: #3f4254;
    box-shadow: none;
    opacity: 0.65;
}

.lm-share-dashboard-modal .modal-footer {
    padding: 1rem 1.75rem 1.5rem;
    border-top: 1px solid #e9edf3;
    background: #ffffff;
}

.lm-share-dashboard-cancel {
    min-width: 100px;
    border-color: #e4e6ef;
    background: #f5f8fa;
    color: #3f4254;
}

.lm-share-dashboard-cancel:hover,
.lm-share-dashboard-cancel:focus {
    border-color: #d8dee9 !important;
    background: #eef3f7 !important;
    color: #3f4254 !important;
}

@media (max-width: 767.98px) {
    .lm-share-dashboard-modal .modal-header,
    .lm-share-dashboard-modal .modal-body,
    .lm-share-dashboard-modal .modal-footer {
        padding-left: 1.25rem;
        padding-right: 1.25rem;
    }

    .lm-share-dashboard-tabs {
        gap: 1rem;
        overflow-x: auto;
        flex-wrap: nowrap;
    }

    .lm-share-dashboard-access-row {
        align-items: flex-start;
        flex-direction: column;
    }

    .lm-share-dashboard-role-button,
    .lm-share-dashboard-access-badge {
        margin-left: 3.25rem;
    }
}

#modal-share-dashboard .modal-content.lm-share-dashboard-modal {
    background: #ffffff !important;
    border-color: #e4e6ef !important;
    color: #5e6278 !important;
}

#modal-share-dashboard .modal-header,
#modal-share-dashboard .modal-body,
#modal-share-dashboard .modal-footer {
    background: #ffffff !important;
}

#modal-share-dashboard .modal-header,
#modal-share-dashboard .modal-footer,
#modal-share-dashboard .lm-share-dashboard-tabs,
#modal-share-dashboard .separator {
    border-color: #e9edf3 !important;
}

#modal-share-dashboard .modal-title,
#modal-share-dashboard .lm-share-dashboard-intro,
#modal-share-dashboard .lm-share-dashboard-access-name,
#modal-share-dashboard .lm-share-dashboard-public-title,
#modal-share-dashboard .lm-share-dashboard-copy-button,
#modal-share-dashboard .lm-share-dashboard-cancel {
    color: #3f4254 !important;
}

#modal-share-dashboard .lm-share-dashboard-role-button {
    color: #7e8299 !important;
}

#modal-share-dashboard .lm-share-dashboard-tabs .nav-link {
    color: #7e8299 !important;
    background: transparent !important;
}

#modal-share-dashboard .lm-share-dashboard-tabs .nav-link.active {
    color: #419fff !important;
    border-bottom-color: #419fff !important;
}

#modal-share-dashboard .lm-share-dashboard-tabs .lm-share-dashboard-disabled-tab,
#modal-share-dashboard .lm-share-dashboard-tabs .lm-share-dashboard-disabled-tab:hover {
    color: #a1a5b7 !important;
}

#modal-share-dashboard .lm-share-dashboard-note,
#modal-share-dashboard .lm-share-dashboard-public-copy,
#modal-share-dashboard .lm-share-dashboard-access-badge {
    color: #7e8299 !important;
}

#modal-share-dashboard .lm-share-dashboard-search-input,
#modal-share-dashboard .lm-share-dashboard-public-input {
    background: #ffffff !important;
    border-color: #d8dee9 !important;
    color: #3f4254 !important;
}

#modal-share-dashboard .lm-share-dashboard-search-input {
    padding-left: 3rem !important;
}

#modal-share-dashboard .lm-share-dashboard-search-input::placeholder,
#modal-share-dashboard .lm-share-dashboard-public-input::placeholder {
    color: #99a1b7 !important;
}

#modal-share-dashboard .lm-share-dashboard-search-input:focus {
    background: #ffffff !important;
    border-color: #419fff !important;
    color: #3f4254 !important;
}

#modal-share-dashboard .lm-share-dashboard-public-card,
#modal-share-dashboard .lm-share-dashboard-role-button,
#modal-share-dashboard .lm-share-dashboard-copy-button,
#modal-share-dashboard .lm-share-dashboard-cancel {
    border-color: #d8dee9 !important;
}

#modal-share-dashboard .lm-share-dashboard-public-card,
#modal-share-dashboard .lm-share-dashboard-role-button,
#modal-share-dashboard .lm-share-dashboard-copy-button {
    background: #ffffff !important;
}

#modal-share-dashboard .lm-share-dashboard-cancel {
    background: #f5f8fa !important;
}

#modal-share-dashboard .lm-share-dashboard-copy-button:disabled {
    opacity: 0.65;
}

#toast-container > .toast-info {
    position: relative !important;
    background-color: #419fff !important;
    background-image: none !important;
    border: 1px solid #2f86de !important;
    box-shadow: 0 12px 28px rgba(65, 159, 255, 0.28) !important;
    color: #ffffff !important;
    opacity: 1 !important;
    padding: 15px 15px 15px 58px !important;
}

#toast-container > .toast-info:hover {
    box-shadow: 0 14px 32px rgba(65, 159, 255, 0.34) !important;
}

#toast-container > .toast-info::before {
    content: "\f017";
    position: absolute;
    top: 50%;
    left: 18px;
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.16);
    color: #ffffff;
    font-family: "Font Awesome 6 Free";
    font-size: 0.95rem;
    font-weight: 900;
    line-height: 1;
}

#toast-container > .toast-info .toast-title,
#toast-container > .toast-info .toast-message {
    color: #ffffff !important;
}

#toast-container > .toast-info .toast-progress {
    background: rgba(255, 255, 255, 0.35) !important;
}

.lm-shared-dashboard-indicator {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1rem;
    height: 1rem;
    font-size: 0.72rem;
    line-height: 1;
    cursor: help;
}

/* Sidebar dashboard names: keep on a single line, ellipsize when too long.
   The native title attribute provides the full name on hover. */
.lm-sidebar-dashboard-name {
    display: inline-block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 150px;
    vertical-align: middle;
}

.lm-shared-dashboard-indicator i {
    line-height: 1;
}

.lm-shared-dashboard-indicator.lm-shared-incoming,
.lm-shared-dashboard-indicator.lm-shared-incoming i {
    color: #3baaf7 !important;
}

.lm-module-help-popover {
    max-width: 280px;
}

.lm-header-info-btn {
    margin-left: 0.15rem !important;
    transform: translateY(-1px);
}

.lm-module-help-popover .popover-body {
    font-size: 0.95rem;
    line-height: 1.55;
    color: #344054;
}

/* Claude Code connect modal — card hover */
.cc-option-card {
    transition: border-color 0.15s ease, background-color 0.15s ease;
}
.cc-option-card:hover {
    border-color: #419FFF !important;
    background-color: #f0f7ff;
}

/* Active Filters Bar */
#kt_app_header {
    flex-wrap: wrap;
}

#active-filters-bar {
    flex-shrink: 0;
    min-height: 0;
    padding-top: 5px;
    padding-bottom: 0px;
}

#kt_app_toolbar.app-toolbar {
    padding-top: 0 !important;
}

.lm-active-filter-pill {
    transition: border-color 0.15s ease;
}

.lm-active-filter-pill:hover {
    border-color: #419FFF !important;
}

.lm-active-filter-pill-remove {
    opacity: 0.5;
    line-height: 1;
    font-size: 16px;
    transition: opacity 0.15s ease;
}

.lm-active-filter-pill-remove:hover {
    opacity: 1;
    color: #e83535 !important;
}

/* Team Activity table — sticky header + first column (Team Overview) */
#team-activity-table-wrapper {
    max-height: 70vh;
    overflow-y: auto;
}

#team-activity-table thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background-color: var(--bs-light);
}

#team-activity-table thead th.sticky-col {
    position: sticky;
    left: 0;
    z-index: 3;
}

#team-activity-table tbody td.sticky-col {
    position: sticky;
    left: 0;
    z-index: 1;
    background-color: var(--bs-body-bg);
}

#team-activity-table .team-activity-team-row td.sticky-col {
    background-color: var(--bs-light);
}

#team-activity-table .team-activity-member-row td.sticky-col {
    background-color: var(--bs-body-bg);
}

/* Bot user rows (RD-2007) ----------------------------------------------
   Marked with a left rail in the org's brand primary (falls back to the
   Leanmote default). No background tint and no row-wide animation — the
   rail + larger robot badge are enough to flag the row as an agent
   without competing with the data. */
#team-activity-table .team-activity-bot-row td:first-child {
    border-left: 4px solid var(--lm-brand-primary, var(--lm-primary-dark));
}

#team-activity-table .team-activity-bot-badge {
    color: var(--lm-brand-primary, var(--lm-primary-dark));
    font-size: 1.35rem;
    line-height: 1;
    vertical-align: middle;
}

/* RD-2161: sidebar count badges (Bottleneck Insights + Discoveries).
 * Metronic's base `.badge` is `inline-flex; align-items:center` but has NO
 * `justify-content` — only `.badge-circle`/`.badge-square` center on the main
 * axis. These pills carry `badge-sm` (min-width: 1.5rem), so a value narrower
 * than that min-width isn't horizontally centered (the digits drift off to one
 * side). Center the content explicitly so single- and double-digit counts sit
 * dead-center in the pill. */
#lm-insights-total-badge,
#lm-discoveries-pending-badge {
    justify-content: center;
}

/* RD-2452 — the Discoveries child row under Settings, shown only when Discoveries
 * has pending items (JS toggles .d-none on the row).
 *
 * It borrows the indent of the real accordion children above it
 * (.menu-link.py-1.ps-4, same as the Performance Delivery sub-items), but swaps
 * their bullet for an ELBOW CONNECTOR: a line that drops out of the Settings row
 * and turns right into this label.
 *
 * Why the elbow and not a chevron on the parent: both were tried. A chevron is the
 * expand/collapse signifier, so it made Settings read as an accordion — which it
 * cannot be, since Settings has to stay a plain link to /settings, and a control
 * that looks interactive but isn't is worse than no control. The elbow states the
 * same relationship ("this branches off that") in the vocabulary of a tree rather
 * than a disclosure widget: nothing about a connector line suggests it folds.
 *
 * The SVG is 30px tall inside a ~28px row on purpose, with negative vertical
 * margins so it can overflow upward without inflating the row — that is what lets
 * the vertical stroke reach into the gap above and read as coming FROM Settings
 * instead of starting in mid-air. If the join ever looks off after a Metronic
 * spacing change, the two numbers to nudge are this margin and the SVG's V15. */
#lm-discoveries-nav-item .menu-title {
    font-size: 0.95rem;
}

.lm-nav-branch {
    display: inline-flex;
    flex: none;
    /* Overflow the row vertically (see above) without changing its height. */
    margin: -0.5rem 0.5rem -0.5rem 0;
    color: currentColor;
    opacity: 0.4; /* a connector, not content — it should be felt, not read */
}

.lm-nav-branch svg {
    display: block;
}

/* Chip stack at the right end of the Performance Delivery tab row.
 *
 * Holds the Insights chip and the join-requests button. Before it existed they
 * were direct children of the row's justify-content-between flex alongside a
 * third chip, so the browser handed EACH of them a share of the free space
 * (freeSpace/3 on top of the row's own gap, plus a redundant ms-3 on two of
 * them) and they read as unrelated things strewn across the width; flex-wrap
 * then let one of them drop under the tabs by itself. Collapsing them into one
 * flex child leaves the row with exactly two — tabs left, chips right — which is
 * why the row itself needs no changes beyond its alignment.
 *
 * They stack instead of sitting side by side. Side by side they had to be parsed
 * left-to-right to be told apart; one per line gives each its own scan target,
 * and their right edges lining up is what makes them read as one group. It also
 * decouples them from the tabs: the row can hold four tabs and every chip
 * without either side deciding when the other wraps.
 *
 * Sized to hold more than it currently does, on purpose — this is where any
 * future "there is something here worth a look" affordance for this row belongs,
 * and it already handles an arbitrary number of them.
 *
 * align-items: flex-end is the horizontal alignment here (cross axis, because
 * this is a column) — it right-aligns chips of differing widths against the same
 * edge, which is the whole reason the stack reads as a block.
 *
 * No vertical margin, deliberately. .lm-pd-insights-badge used to carry a
 * 0.35rem bottom lift to keep it off the tab links' pb-4 underline, back when it
 * sat beside the tabs on one line; the stack is taller than the tabs and the row
 * top-aligns (align-items-start on the row, so the tabs land level with the FIRST
 * chip), so nothing here relates to that underline any more and a bottom margin
 * would only pad the row out. Top edges align on their own: the tab link's
 * 0.5rem padding-top puts its text within ~2px of the first chip's centre, which
 * is inside the tolerance an optical nudge would have been correcting for. */
.lm-pd-tabrow-chips {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    /* Tighter than a horizontal row would want: stacked, the chips share a
     * vertical edge, so 8px is already a clear break between two 38px boxes
     * without letting the group drift apart. Just under the 9px gap INSIDE each
     * chip, so a chip still binds to itself more tightly than to its neighbour. */
    gap: 0.5rem; /* 8px */
}

/* Every chip in here ships with .d-none and earns its place only when its own
 * count comes back > 0, so on a clean org this is a live element with nothing
 * inside it. It has no surface of its own (no padding, border or background) so
 * it draws nothing either way — but a zero-width flex child still claims the
 * row's 1rem column-gap and would make the tabs wrap 1rem earlier than they
 * need to. :has() is live, so the first chip to drop its .d-none brings the
 * cluster straight back.
 *
 * Written as :not(:has()) over a display: flex base on purpose: where :has() is
 * unsupported the whole rule is dropped and the cluster simply stays visible
 * (the pre-RD-2467 behaviour). The inverse — display: none by default, revealed
 * by :has() — would fail closed and hide the chips outright. */
.lm-pd-tabrow-chips:not(:has(> :not(.d-none))) {
    display: none;
}

/* RD-2179: Performance Delivery → Bottleneck Insights badge.
 * Lives at the far right of the dashboard tab row and deep-links into
 * Bottleneck Insights for the current view, showing that view's active-insight
 * count. It is the affordance INTO the BI world, so it borrows the BI attention
 * red (--ct-sev-high #ef4444 / #dc2626 / #fef2f2) rather than the dashboard
 * celeste, to draw the eye to a view that has signal worth acting on.
 *
 * RD-2179 — reads as a quiet "N insights to act on here" cue, not a loud chip.
 * Just two parts: a red count "pill" (white digit, carried over from the BI
 * feed's own header-count language) as the hero, trailed by the "Insights"
 * label. Motion is deliberately minimal because the tab row is seen dozens of
 * times a day: a calm red tint deepen on hover, a real scale-on-press, on the
 * BI module's own --ct-ease-out curve. Hidden until the loader confirms
 * count > 0 (the .d-none is removed in JS).
 *
 * RD-2452 made this block SHARED with a second chip — Discovery's "N to map",
 * → /discoveries — and RD-2467 removed that chip from the tab row again, so it is
 * back to one consumer. Keep it written as though there were more: everything
 * here is generic to "attention chip that deep-links somewhere", nothing assumes
 * Bottleneck Insights beyond the red it borrows, and there is no modifier for the
 * one chip that uses it. The reason to hold that line is what RD-2452 ran into:
 * two chips of this red sitting side by side, identical except for their label,
 * read as a rendering slip rather than as two signals — so a second consumer
 * should either look the same and be told apart by words, or differ in a way a
 * user can name. Placement in the row is not this component's job either; that
 * lives in .lm-pd-tabrow-chips above. */
.lm-pd-insights-badge {
    /* Bottleneck Insights attention-red family (mirrors the BI module's own
     * severity/anomaly tokens: --ct-sev-high #ef4444, the #dc2626 red text token,
     * the #fef2f2 light-red surface) so the badge speaks BI's "needs a look" red. */
    --lm-bi-accent:        #dc2626; /* count-pill fill; white number passes AA on this */
    --lm-bi-accent-strong: #b91c1c; /* deepened red for hover + label/border firming */
    --lm-bi-accent-soft:   #fee2e2; /* one-step-deeper red tint for hover surface */
    --lm-bi-accent-softer:  #fef2f2; /* resting light-red surface (BI's own) */
    --lm-bi-accent-border: #f6cccc; /* red-tinted hairline at rest */
    --lm-bi-accent-border-hover: #f1b0b0; /* firmer red hairline on hover */
    /* Strong ease-out, identical to the Bottleneck Insights module token so the
     * badge and its destination share one motion language. */
    --lm-bi-ease-out:      cubic-bezier(0.23, 1, 0.32, 1);

    display: inline-flex;
    align-items: center;
    gap: 0.5625rem; /* 9px */
    padding: 0.4375rem 0.6875rem 0.4375rem 0.8125rem; /* 7px 11px 7px 13px */
    border: 1px solid var(--lm-bi-accent-border);
    border-radius: 0.5625rem; /* 9px */
    background: var(--lm-bi-accent-softer);
    color: var(--lm-bi-accent-strong);
    font-size: 0.875rem; /* 14px */
    font-weight: 600;
    line-height: 1;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color 150ms var(--lm-bi-ease-out),
                border-color 150ms var(--lm-bi-ease-out),
                color 150ms var(--lm-bi-ease-out),
                transform 130ms var(--lm-bi-ease-out);
}

/* Reveal: the badge is shown once per page load (the loader strips .d-none when
 * count > 0), so a gentle one-shot fade is worth it — appearing with no
 * transition reads as a layout glitch. Never animates from scale(0): starts at
 * 0.96 + a slight downward offset so it settles onto the baseline, not pops in
 * from nothing. */
.lm-pd-insights-badge:not(.d-none) {
    animation: lm-pd-insights-badge-in 240ms var(--lm-bi-ease-out) both;
}

@keyframes lm-pd-insights-badge-in {
    from {
        opacity: 0;
        transform: translateY(-2px) scale(0.96);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

/* The count is the load-bearing number — render it as a small red pill (BI's
 * attention red) with a white digit so the eye lands on "how many" first,
 * mirroring the BI feed's header-count chip. Tabular figures keep single/double
 * digits from shifting the trailing word. */
.lm-pd-insights-badge__count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.375rem; /* 22px */
    height: 1.375rem; /* 22px */
    padding: 0 0.4375rem; /* 7px */
    border-radius: 0.4375rem; /* 7px */
    background: var(--lm-bi-accent);
    color: #ffffff;
    font-size: 0.8125rem; /* 13px */
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    transition: background-color 150ms var(--lm-bi-ease-out);
}

/* The "Insights" label in a deepened BI red, legible on the light-red surface.
 * The count pill carries the meaning; the word just disambiguates. */
.lm-pd-insights-badge__label {
    font-weight: 600;
    color: var(--lm-bi-accent-strong);
    letter-spacing: -0.005em;
}

/* Trailing arrow: a quiet "click me" affordance, not decoration. Rendered as an
 * inline SVG (not a font glyph) so it stays crisp and solid red at every zoom,
 * independent of the product font. stroke="currentColor" inherits the badge's
 * deepened BI red. It sits still at rest and nudges ~3px to the right on hover —
 * the small directional cue that this badge takes you somewhere (the BI module).
 * transform-only on the BI ease-out curve so it stays GPU-cheap; movement is
 * dropped under reduced motion. */
.lm-pd-insights-badge__arrow {
    display: inline-flex;
    align-items: center;
    color: var(--lm-bi-accent-strong);
    transition: transform 150ms var(--lm-bi-ease-out);
}

.lm-pd-insights-badge__arrow svg {
    display: block;
    width: 0.875rem; /* 14px */
    height: 0.875rem; /* 14px */
}

/* Hover/focus: deepen the tint and firm up the border. No solid fill, no drop
 * shadow — a tab-row accent should respond, not shout. Gated to real pointers
 * so a tap on touch doesn't leave a stuck hover state. */
@media (hover: hover) and (pointer: fine) {
    .lm-pd-insights-badge:hover {
        background: var(--lm-bi-accent-soft);
        border-color: var(--lm-bi-accent-border-hover);
    }

    .lm-pd-insights-badge:hover .lm-pd-insights-badge__count {
        background: var(--lm-bi-accent-strong);
    }

    .lm-pd-insights-badge:hover .lm-pd-insights-badge__arrow {
        transform: translateX(3px);
    }
}

.lm-pd-insights-badge:focus-visible {
    background: var(--lm-bi-accent-soft);
    border-color: var(--lm-bi-accent-border-hover);
    outline: 2px solid var(--lm-bi-accent);
    outline-offset: 2px;
}

/* Press feedback: a subtle scale, the physical-button idiom — not a positional
 * nudge. scale() also pulls the count pill and label in together. */
.lm-pd-insights-badge:active {
    transform: scale(0.97);
}

/* Reduced motion: keep the color/tint changes that aid comprehension, drop all
 * positional movement (press scale + the reveal's translate/scale). The reveal
 * becomes a plain opacity fade. */
@media (prefers-reduced-motion: reduce) {
    .lm-pd-insights-badge {
        transition: background-color 150ms var(--lm-bi-ease-out),
                    border-color 150ms var(--lm-bi-ease-out),
                    color 150ms var(--lm-bi-ease-out);
    }

    .lm-pd-insights-badge:active {
        transform: none;
    }

    .lm-pd-insights-badge__arrow {
        transition: none;
    }

    .lm-pd-insights-badge:hover .lm-pd-insights-badge__arrow {
        transform: none;
    }

    .lm-pd-insights-badge:not(.d-none) {
        animation: lm-pd-insights-badge-fade 200ms var(--lm-bi-ease-out) both;
    }
}

@keyframes lm-pd-insights-badge-fade {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* Join-requests button, trimmed to the chip height.
 *
 * It shares .lm-pd-tabrow-chips with the Insights chip, and Metronic's btn-sm box
 * is 47.6px tall against that chip's 38px (a 28px .badge-circle inside
 * calc(0.55rem + 1px) of padding). Stacked one per line that 10px reads as one
 * rung of the ladder being the wrong size — a vertical stack makes uneven box
 * heights far more obvious than a horizontal row ever did, because the eye runs
 * straight down the edges. Dropping its count to badge-sm (24px) and padding it
 * by 7px rebuilds the same sandwich the chip makes around its 22px count pill, so
 * both land on one box. Horizontal padding is left alone on purpose: a button is
 * allowed to be roomier than a chip, the stack is right-aligned so the extra
 * width falls to the left, and only the height was load-bearing here.
 *
 * Selected by id deliberately. Metronic delivers that padding through
 * `.btn:not(…)×8.btn-sm`, a 0,10,0 selector no class hook can outrank; an id is
 * 1,0,0 and wins outright. Same trick and same reason as
 * #lm-insights-total-badge.lm-badge--dot below. */
#lm-jr-badge {
    padding-top: 0.4375rem;    /* 7px — matches .lm-pd-insights-badge */
    padding-bottom: 0.4375rem; /* 7px */
}

/* RD-2416 — "presence" (dot) state for the insight count badges.
 *
 * The exact per-role count only exists AFTER the active feed has run its LLM
 * role classification (persisting verdicts). Both badges fire on page load,
 * before that has happened, so instead of showing a number that later shrinks
 * (the 20 → 10 jump) they show a small DOT — "you have insights here" — until
 * the count is known to be exact, then they swap to the real number. No new
 * motion: these badges are seen on nearly every page, so the dot just reuses
 * each badge's existing one-shot reveal rather than adding its own animation. */

/* Actions Hub sidebar total badge → red notification dot (no number). The
 * id+class selector (specificity 0,1,1,0) wins over both Metronic's .badge-sm
 * min-width AND Bootstrap's `.badge:empty { display: none }` (0,0,2,0) — the
 * dot branch empties the badge (textContent=''), so WITHOUT an explicit display
 * here the emptied badge would collapse to display:none and show nothing. */
#lm-insights-total-badge.lm-badge--dot {
    display: inline-flex; /* override .badge:empty { display:none } for the dot */
    min-width: 0;
    width: 0.6875rem; /* 11px — big enough to read as a clear presence cue */
    height: 0.6875rem; /* 11px */
    padding: 0;
    border-radius: 50%;
    font-size: 0; /* never render a stray glyph inside the dot */
    line-height: 0;
}

/* Per-view "Insights to resolve" badge → the red count pill keeps its footprint
 * but shows a centered white dot instead of a digit, so the tab row does not
 * reflow when the exact number later arrives. The "Insights to resolve" label
 * and arrow stay, so it still reads as "there are insights to resolve here". */
.lm-pd-insights-badge--pending .lm-pd-insights-badge__count {
    font-size: 0; /* hide the digit text node; the ::after dot carries meaning */
}

.lm-pd-insights-badge--pending .lm-pd-insights-badge__count::after {
    content: "";
    display: block;
    width: 0.375rem; /* 6px */
    height: 0.375rem; /* 6px */
    border-radius: 50%;
    background: #ffffff;
}

/* RD-2261 — Channel picker (Slack / Email) segmented control.
   Upgrades a native <select data-channel-picker>; the select is kept hidden as
   the value source. Used in the Performance Delivery alert popover and the
   Actions Hub alert form modal. */
.lm-channel-picker { position: relative; }
.lm-channel-picker__native { display: none !important; }
.lm-channel-seg { display: flex; flex-wrap: wrap; gap: 6px; }
.lm-channel-seg__opt {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 12px;
    border: 1px solid var(--lm-light-grey, #e0e0e0);
    border-radius: 8px;
    background: var(--lm-white, #fff);
    color: var(--lm-strong-gray, #666);
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.2;
    cursor: pointer;
    transition: border-color 150ms ease, background-color 150ms ease,
                color 150ms ease, transform 120ms cubic-bezier(0.23, 1, 0.32, 1);
}
.lm-channel-seg__opt:hover { border-color: var(--lm-primary-light, #419FFF); }
.lm-channel-seg__opt:active { transform: scale(0.97); }
.lm-channel-seg__opt.is-active {
    border-color: var(--lm-primary-light, #419FFF);
    background: rgba(65, 159, 255, 0.08);
    color: var(--lm-primary-dark, #1C2E62);
}
.lm-channel-seg__opt:focus-visible { outline: 2px solid var(--lm-primary-light, #419FFF); outline-offset: 2px; }
.lm-cp-logo { width: 16px; height: 16px; object-fit: contain; display: block; }
.lm-cp-mail { font-size: 15px; line-height: 1; color: var(--lm-secondary-dark, #4F7AB0); }

/* RD-2496 — a channel the organization can't be reached on stays VISIBLE but
   inert: present enough to be discovered, quiet enough to read as "not yet".
   Every affordance that says "pressable" is withdrawn (hover border, press
   scale, pointer) so the segment can't invite a click it will refuse. */
.lm-channel-seg__opt--disabled {
    border-color: var(--lm-light-grey, #e0e0e0);
    background: rgba(0, 0, 0, 0.02);
    color: var(--lm-medium-grey, #999);
    cursor: not-allowed;
    opacity: 0.65;
}
.lm-channel-seg__opt--disabled:hover { border-color: var(--lm-light-grey, #e0e0e0); }
.lm-channel-seg__opt--disabled:active { transform: none; }
/* Desaturating the logo is what actually reads as "off" at a glance — opacity
   alone leaves Slack's colours legible enough to still look enabled. */
.lm-channel-seg__opt--disabled .lm-cp-logo { filter: grayscale(1); }
.lm-channel-seg__opt--disabled .lm-cp-mail { color: var(--lm-medium-grey, #999); }

/* The persistent note under the control: why the channel is off, and the way
   out. Celeste tint rather than a warning colour — nothing is broken, there is
   just something to connect. */
.lm-channel-picker__note {
    margin: 8px 0 0;
    padding: 8px 10px;
    border: 1px solid rgba(65, 159, 255, 0.14);
    border-radius: 8px;
    background: rgba(65, 159, 255, 0.06);
    font-size: 11.5px;
    font-weight: 500;
    line-height: 1.45;
    color: var(--lm-strong-gray, #666);
}
.lm-channel-picker__connect {
    color: var(--lm-primary-light, #419FFF);
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
    transition: color 150ms ease;
}
.lm-channel-picker__connect:hover { color: var(--lm-primary-dark, #1C2E62); text-decoration: underline; }
.lm-channel-picker__connect:focus-visible { outline: 2px solid var(--lm-primary-light, #419FFF); outline-offset: 2px; border-radius: 3px; }

@media (prefers-reduced-motion: reduce) {
    .lm-channel-seg__opt { transition-property: border-color, background-color, color; }
    .lm-channel-seg__opt:active { transform: none; }
    .lm-channel-picker__connect { transition: none; }
}

/* ============================================================ */
/* Sticky tab bars (RD-2483)                                    */
/* ============================================================ */
/* Pins the tab row (and, on Performance Delivery, its chip stack)
   under the fixed app header while the page scrolls. The offset is
   --lm-sticky-top, kept in sync with the header's real height by
   js/utils/sticky-tabs.js — NOT --bs-app-header-height, which
   Metronic pins to 74px on <body> as soon as the page scrolls and
   would win over any measured value for everything below it.
   z-index sits above the in-page sticky helpers (Team Overview
   frozen columns: 1-3, feed back button: 50) and below the app
   header (100). */
.lm-sticky-tabs {
    position: sticky;
    top: var(--lm-sticky-top, 74px);
    z-index: 60;
    background-color: var(--bs-app-bg-color, #fcfcfc);
    /* box-shadow only: the background must flip in the same instant as the
       header's own bg (.app-header has transition: none), or the two
       surfaces briefly disagree while the minimize state toggles. */
    transition: box-shadow 200ms cubic-bezier(0.23, 1, 0.32, 1);
    /* Bleed over the .app-container gutters (30px desktop / 20px mobile,
       see style.bundle.css) with compensating padding, so the pinned
       background reaches the container edges like the header above does
       instead of leaving page-bg strips at both sides. Net content
       position is unchanged, so nothing shifts when pinning. */
    margin-left: -30px;
    margin-right: -30px;
    padding-left: 30px;
    padding-right: 30px;
}

@media (max-width: 991.98px) {
    .lm-sticky-tabs {
        margin-left: -20px;
        margin-right: -20px;
        padding-left: 20px;
        padding-right: 20px;
    }
}

/* The bar whitens on the SAME body attribute Metronic flips to whiten
   the header on scroll, reading the same variable — so the two surfaces
   can never disagree on the shade. (At rest the header is transparent
   over the page bg, and so is the bar's base rule above.) */
[data-kt-app-header-minimize="on"] .lm-sticky-tabs {
    background-color: var(--bs-app-header-minimize-bg-color, #ffffff);
}

/* Elevation cue only while actually pinned (class toggled by
   sticky-tabs.js), so the row keeps its flat look at rest. */
.lm-sticky-tabs.lm-stuck {
    box-shadow: 0 8px 12px -8px rgba(28, 46, 98, 0.16);
}

/* On pages with a sticky tab bar the header's own minimize shadow is
   suppressed for the WHOLE minimized state: it paints ABOVE the bar
   (z-index 100 vs 60) and its 30px blur washes a gray band across the
   bar's white — and if it were only suppressed while the bar is pinned
   (.lm-stuck), it would flash back on in the few px between the bar
   unpinning and the scroll reaching top (AI Return / Actions Hub sit
   ~8px under the header, so that window is a visible blink on the way
   up). The pinned bar carries the elevation shadow instead. */
body[data-kt-app-header-minimize="on"]:has(.lm-sticky-tabs) #kt_app_header {
    box-shadow: none;
}

[data-bs-theme="dark"] .lm-sticky-tabs.lm-stuck {
    box-shadow: 0 8px 12px -8px rgba(0, 0, 0, 0.55);
}

/* ============================================================ */
/* Settings hub page-head bar                                   */
/* ============================================================ */
/* The hub's page-head bar (#kt_app_toolbar on Settings, Users, Boards
   and Discoveries) pins under the app header so the area title stays
   on screen: people scrolling a long section could not tell they were
   still standing inside Settings. It reuses .lm-sticky-tabs for the
   pin, the measured offset and the .lm-stuck shadow; these rules are
   the corrections the toolbar needs on top of that shared base.

   Every one is written as #kt_app_toolbar.<class> on purpose:
   custom.css is linked BEFORE style.bundle.css (see head.php), so at
   equal specificity the theme wins — only the id selector reliably
   beats the bundle's own .app-toolbar rules. */
#kt_app_toolbar.lm-hub-head {
    /* The bundle pins .app-toolbar to a flat 55px on ≥992px, which the
       Boards bar (title + subtitle) already overflows. Let it size to
       its content so the pinned background covers all of it — and so
       the height cannot change at the moment it pins, which would move
       the flow underneath and bounce the scroll. */
    height: auto;
    /* .lm-sticky-tabs bleeds -30px/-20px over the .app-container
       gutters because it is normally used INSIDE that container. The
       toolbar is already full-bleed, so the bleed would push it past
       the viewport and add horizontal scroll. */
    margin-left: 0;
    margin-right: 0;
    padding-left: 0;
    padding-right: 0;
    /* Opaque, and the same shade it already has at rest, so pinning
       changes nothing but the elevation. */
    background-color: var(--bs-app-toolbar-base-bg-color, #ffffff);
}

/* Follow the header's shade on scroll, like .lm-sticky-tabs does — restated
   here because the id selector above would otherwise outrank it. */
[data-kt-app-header-minimize="on"] #kt_app_toolbar.lm-hub-head {
    background-color: var(--bs-app-header-minimize-bg-color, #ffffff);
}

/* The section segment of the pinned title ("Settings · Work classification").
   Hidden at rest — the section already titles the card below — and revealed
   only while the bar is pinned, which is when the card's own heading has
   scrolled away. display, not opacity: reserving its width at rest would
   indent the title on the pages where the segment is the "Settings ·"
   prefix. nowrap so the segment itself cannot break mid-phrase; the whole
   title is kept to one line further down. */
.lm-hubctx {
    display: none;
    white-space: nowrap;
}
/* Desktop only. Under 992px the title has ~335px to live in, and the longest
   pair ("Configuración · Work classification") would wrap to a second line
   while pinned — growing the bar and pushing the content below it down. The
   narrow layout also stacks the hub menu on top instead of pinning it, so the
   bar is not carrying the context alone there. */
@media (min-width: 992px) {
    .lm-stuck .lm-hubctx {
        display: inline;
        /* Entering element → ease-out, and short: the bar itself is what the
           eye is following, the segment should just be there. */
        animation: lm-hubctx-in 160ms cubic-bezier(0.23, 1, 0.32, 1);
    }
}
@keyframes lm-hubctx-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
    .lm-stuck .lm-hubctx { animation: none; }
}

/* Back to top, at the far end of the bar. Hidden until the bar pins, because
   until then you are already at the top and it would be a button that does
   nothing. visibility (not display) keeps its slot in the layout at rest, so
   the reveal cannot change the bar's height — and unlike a bare opacity:0 it
   also keeps the invisible button out of the tab order and the a11y tree.
   Entering → ease-out; leaving is instant, which is the right asymmetry: by
   then the page has already scrolled to where the button was pointing. */
.lm-hub-head .lm-hub-top {
    visibility: hidden;
    opacity: 0;
    /* Keeps its size; the title is what gives way when the row runs short. */
    flex: none;
    transition: opacity 160ms cubic-bezier(0.23, 1, 0.32, 1),
                transform 160ms cubic-bezier(0.23, 1, 0.32, 1);
}
.lm-hub-head.lm-stuck .lm-hub-top {
    visibility: visible;
    opacity: 1;
}
/* Press feedback — the theme styles hover for .btn-light but nothing on press,
   and this button is the one control in the bar. */
.lm-hub-head .lm-hub-top:active {
    transform: scale(0.97);
}
@media (prefers-reduced-motion: reduce) {
    .lm-hub-head .lm-hub-top { transition: opacity 160ms linear; }
    .lm-hub-head .lm-hub-top:active { transform: none; }
}

/* The pinned title never wraps. With the button holding ~150px of the row, a
   long pair ("Configuración · Cobertura de integraciones") could reach a second
   line just as the bar pins — growing the bar and pushing the page down under
   the reader's eyes. It truncates instead, which costs nothing: the section's
   full title sits right below, inside the card. The min-width:0 is what lets it
   truncate at all — flex items refuse to shrink past their content otherwise,
   and the row would overflow sideways instead. */
.lm-hub-head .page-title {
    min-width: 0;
}
.lm-hub-head .page-title > .page-heading {
    min-width: 0;
}
.lm-hub-title {
    display: block;
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* ============================================================ */
/* Pinned content chrome on the hub pages                        */
/* ============================================================ */
/* Layers 3+ of a hub's pinned stack (1 = the app header, 2 = the
   page-head bar): the section head, the tab row, a second tab row,
   and under all of them the tables' column headers. Scrolling a long
   section used to cost you which section you were in, which tab you
   were on and what each column meant.

   A band opts in with data-lm-pin="N", N counting down from the bar,
   and js/utils/sticky-tabs.js publishes its measured height as
   --lm-pin-N-h. Offsets compose those variables on top of
   --lm-sticky-top-stacked (header + bar) — no hardcoded heights, so a
   JS failure leaves a pin a few px off instead of a broken page.

   Each band pins at a CONSTANT height: the breathing room it needs
   while pinned is added as padding and taken straight back out of the
   flow as a negative margin. A band that grew or shrank as it pinned
   would move everything below it and bounce the scroll.

   The doubled attribute selector is for specificity only: these bands
   carry Metronic spacing utilities (mb-8, mt-8), style.bundle.css
   loads after this file, and a single attribute would lose the tie. */
.app-content [data-lm-pin][data-lm-pin] {
    position: sticky;
    background-color: #fff;
    margin-top: -10px;
    padding-top: 10px;
    /* z-index below the page-head bar's 60, above the in-card sticky
       helpers (the board lists' group headers sit at 1). */
    z-index: 12;
}
.app-content [data-lm-pin="1"][data-lm-pin] {
    top: var(--lm-sticky-top-stacked, 129px);
}
.app-content [data-lm-pin="2"][data-lm-pin] {
    top: calc(var(--lm-sticky-top-stacked, 129px) + var(--lm-pin-1-h, 0px));
    z-index: 11;
}
.app-content [data-lm-pin="3"][data-lm-pin] {
    top: calc(var(--lm-sticky-top-stacked, 129px) + var(--lm-pin-1-h, 0px) + var(--lm-pin-2-h, 0px));
    z-index: 10;
}
/* El cuarto nivel no lo mide sticky-tabs.js: escanea una vez al cargar, y esta
   banda vive dentro de contenido que se vuelve a dibujar. No hace falta que la
   mida —nadie compone offsets sobre --lm-pin-4-h, porque es la última— así que
   el `top` de CSS alcanza. Lo único que se pierde es la sombra de `lm-stuck`,
   que es una señal y no una posición. */
.app-content [data-lm-pin="4"][data-lm-pin] {
    top: calc(var(--lm-sticky-top-stacked, 129px) + var(--lm-pin-1-h, 0px) + var(--lm-pin-2-h, 0px) + var(--lm-pin-3-h, 0px));
    z-index: 9;
}

/* Both cues are shadows, never a border: a border would add a px of
   height at the exact moment the band pins. The hairline marks every
   pinned band; the elevation belongs to the deepest one alone, so the
   stack reads as one surface instead of a pile of drop shadows. */
.app-content [data-lm-pin].lm-stuck {
    box-shadow: 0 1px 0 #f1f1f4;
}
.app-content [data-lm-pin].lm-stuck.lm-pin-last {
    box-shadow: 0 1px 0 #f1f1f4, 0 8px 12px -10px rgba(28, 46, 98, 0.16);
}

/* Column headers, pinned under whatever bands the page declared —
   absent layers resolve to 0px through the fallbacks. Turned on by the
   body class sticky-tabs.js sets when it finds pinned bands, so this
   reaches the hub pages only.

   background-color is not optional: the theme paints cells with a
   transparent --bs-table-bg, and a see-through header would have rows
   sliding visibly through it. border-collapse drops a sticky cell's
   own border, so the header's rule is painted as an inset shadow.

   The child chain is specificity, not decoration. DataTables 2 sets
   `position: relative` on every SORTABLE header cell to anchor its sort
   arrow, and its selector (table.dataTable thead > tr > th.dt-orderable-asc)
   is (0,2,4) — one type selector more than a plain `thead th` here. It won
   `position` and lost `top`, which is the worst of both: the sortable cells
   stayed in the flow and were shifted DOWN by the whole pin stack, so the
   header row tore in two — the columns that only filter (orderable: false)
   pinned as intended while the sortable ones landed a few rows into the
   table, on top of the data. `table > thead > tr > th` is (0,2,5) and keeps
   the pair together. Sticky is still a containing block, so the sort arrow
   goes on anchoring to its cell. */
body.lm-pinned-page .app-content table > thead > tr > th {
    position: sticky;
    top: calc(var(--lm-sticky-top-stacked, 129px) + var(--lm-pin-1-h, 0px) + var(--lm-pin-2-h, 0px) + var(--lm-pin-3-h, 0px));
    z-index: 2;
    background-color: #fff;
    box-shadow: inset 0 -1px 0 #f1f1f4;
}
/* A table inside a modal, an offcanvas or its own scroll box scrolls
   against that box, not the page — pinning its header to the page's
   stack would park it in the middle of the panel.

   It carries the same child chain as the rule above for the same reason:
   the exclusion has to outrank BOTH the pin and DataTables' relative, and
   spelling the chain out makes that visible instead of leaving it to whether
   the reader knows :is() takes the specificity of its most specific argument
   (here .modal / .offcanvas / [data-kt-scroll] — all one class, so (0,3,5)
   holds through every branch of the list).

   `relative` with no offset, not `static`: DataTables draws its sort arrow as
   an absolutely-positioned `span.dt-column-order` (right: 12px; top: 0;
   bottom: 0) and needs the cell as its containing block. A static cell hands
   the arrow to whatever is positioned above it — .modal-content — and it
   stretches to that box's height, landing off its own column. `relative`
   renders identically to `static` here and keeps the anchor.

   `top: auto` and `z-index: auto` are what make it render identically. This
   rule only overrides `position`, so the rest of the pin rule stays in the
   cascade, and positioning the cell wakes up two declarations that were inert
   while it was static: `top`, which would offset the cell down by the whole
   stack (the very bug this pair of rules exists to avoid), and `z-index: 2`,
   which would paint the header OVER anything a row opens across it — a
   dropdown that flips upward, a tooltip — since those carry no z-index of
   their own. Both are given back to the panel's own stacking order. */
body.lm-pinned-page .app-content :is(.modal, .offcanvas, [data-kt-scroll="true"]) table > thead > tr > th {
    position: relative;
    top: auto;
    z-index: auto;
    box-shadow: none;
}

/* .table-responsive is a scroll container, and a sticky header inside
   one pins to that container instead of to the page — which, since the
   wrapper is only as tall as its table, means it never appears to pin
   at all. clip + visible is the one overflow pair that keeps the
   horizontal clipping without creating a scrollport. These tables are
   meant to fit their card; they never scroll sideways. */
body.lm-pinned-page .app-content .table-responsive {
    overflow-x: clip;
    overflow-y: visible;
}
/* Under 992px a card is narrow enough that a wide table can genuinely
   need the sideways scroll, and clipping it would hide columns with no
   way to reach them. The scroll wins there and the header does not pin. */
@media (max-width: 991.98px) {
    body.lm-pinned-page .app-content .table-responsive {
        overflow-x: auto;
    }
}

/* ---------------------------------------------------------------------------
 * "How does this work?" blocks (_howto-panel.php) and the terms that
 * carry a tooltip inside them. Global because the same markup is rendered by
 * the integrations modals and by the Boards page.
 * ------------------------------------------------------------------------ */

/* The chevron points at what the press will do. */
.lm-howto__chev {
    transition: transform 0.18s cubic-bezier(0.23, 1, 0.32, 1);
}

[aria-expanded="false"] .lm-howto__chev {
    transform: rotate(-90deg);
}

@media (prefers-reduced-motion: reduce) {
    .lm-howto__chev {
        transition: none;
    }
}

/* A term that opens its own definition when pressed — the Inception / Delivery
   headers and switch labels, driven by js/utils/term-tip.js. The
   ki-information-2 glyph carries the discovery: a dotted underline alone was not
   findable, which is the whole point of a definition nobody knows to look for.

   The trigger is a real button: it is pressed, not hovered, and a button is
   what a keyboard can reach. Styled to sit inline inside a column header or
   beside a switch label, so it reads as the label it replaces plus a glyph.

   Everything inherits so the button reads as the text it replaced: in a column
   header it picks up the row's uppercase muted style, and where the caller adds
   utility classes (fs-7, fw-semibold) those win — style.bundle.css loads after
   this file, so Metronic's utilities beat these inherits by cascade order. */
.lm-tip {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font-family: inherit;
    font-size: inherit;
    font-weight: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    text-align: inherit;
    white-space: nowrap;
    cursor: pointer;
}

.lm-tip > i {
    color: #99a1b7;
    transition: color 160ms cubic-bezier(0.23, 1, 0.32, 1);
}

.lm-tip:hover > i,
.lm-tip[aria-expanded="true"] > i {
    color: #1b84ff;
}

.lm-tip:focus-visible {
    outline: 2px solid #1b84ff;
    outline-offset: 3px;
    border-radius: 0.25rem;
}

/* Positioned by term-tip.js off the trigger's viewport rect. Fixed rather than
   absolute so no overflow ancestor can clip it, and above the modal's 1055. */
.lm-tip__panel {
    position: fixed;
    z-index: 1085;
    display: none;
    padding: 0.75rem 0.875rem;
    border: 1px solid #f1f1f4;
    border-radius: 0.475rem;
    background: #fff;
    box-shadow: 0 0.5rem 1.5rem rgba(76, 87, 125, 0.15);
    color: #4b5675;
    font-size: 0.85rem;
    font-weight: 400;
    line-height: 1.55;
    letter-spacing: normal;
    text-transform: none;
    white-space: normal;
}

.lm-tip__panel--open {
    display: block;
}

/* ============================================================================
 * RD-2724 — Insights analysis toggle
 *
 * Two surfaces, one preference. Anyone who can edit the view flips it from the
 * switch in the Edit View modal (.lm-view-insights below); someone who
 * only has the view shared with them never opens that modal, so they get the
 * icon button in the header instead.
 *
 * The icon borrows the Metronic btn-secondary shape so the header row stays one
 * consistent set of controls — but unlike its neighbours it carries STATE, and
 * only the glyph says so. An earlier cut filled the whole button indigo, which
 * made a control at rest look like an alert planted in a row of quiet icons.
 * The grey background stays put and the bolt does the talking: celeste when the
 * view is analysed, grey when it is not.
 *
 * Celeste is the app's own accent (--lm-primary-light), not the Bottleneck
 * Insights indigo: this button lives on Performance Delivery, among Performance
 * Delivery's controls, and should look like it belongs to them.
 *
 * OFF is one step lighter than the row's other glyphs rather than identical to
 * them — enough to read as "off" beside them, not so much that it reads as an
 * error. Hover darkens it the way the neighbouring icons darken; the ON colour
 * does not shift, because the button's own background hover already answers the
 * pointer and moving both at once is noise.
 *
 * Selectors carry .btn to outrank Metronic's own .btn-secondary colour rules.
 * ========================================================================= */
.lm-insights-toggle {
    --lm-it-on:        #419FFF; /* --lm-primary-light */
    --lm-it-off:       #99a1b7; /* gray-500 */
    --lm-it-off-hover: #4b5675; /* gray-700, same target the row's icons hover to */
}

.btn.lm-insights-toggle > i {
    color: var(--lm-it-off);
    /* Named property, not `all`: the button also scales on press, and animating
       everything makes the press feel mushy. */
    transition: color 150ms cubic-bezier(0.23, 1, 0.32, 1);
}

.btn.lm-insights-toggle.is-on > i {
    color: var(--lm-it-on);
}

@media (hover: hover) and (pointer: fine) {
    .btn.lm-insights-toggle:hover > i {
        color: var(--lm-it-off-hover);
    }

    /* Not a no-op: without it the rule above turns the ON glyph grey on hover. */
    .btn.lm-insights-toggle.is-on:hover > i {
        color: var(--lm-it-on);
    }
}

/* Confirms the press landed before the dialog opens. */
.lm-insights-toggle:active {
    transform: scale(0.94);
}

.lm-insights-toggle[disabled] {
    opacity: 0.6;
    cursor: default;
}

@media (prefers-reduced-motion: reduce) {
    .lm-insights-toggle:active {
        transform: none;
    }
}

/* ============================================================================
 * RD-2724 — Insights analysis switch (Edit View modal)
 *
 * A settings row, not an alert. It deliberately does NOT borrow the
 * .lm-pd-insights-badge red: that red means "something needs a look", and this
 * control means "should we look at all".
 *
 * It takes the dialog's own accent rather than Bottleneck Insights' brand
 * indigo. An indigo panel in a dialog whose Save button and other switches are
 * Metronic blue read as a second design system dropped into the middle of the
 * first. Everything here comes from Metronic's tokens — --bs-primary-light for
 * the surface, --bs-primary for the glyph, and the switch simply inherits its
 * checked colour rather than overriding it — so this row cannot drift from the
 * dialog around it, and a theme change carries.
 *
 * Borderless on purpose: --bs-primary-light is already distinct enough against
 * the modal's white, and a hairline in some third colour is the kind of detail
 * that turns one panel into its own little component.
 *
 * The var() fallbacks are the light-theme values verbatim. Metronic defines
 * these under [data-bs-theme="light"], which its own KTThemeMode script stamps
 * on <html> at DOMContentLoaded — so they resolve in practice, but a panel with
 * no background is not the failure mode to leave to a script.
 * ========================================================================= */
.lm-view-insights {
    margin-top: 1.25rem;
    padding: 0.875rem 1rem;
    border-radius: 0.625rem;
    background: var(--bs-primary-light, #e9f3ff);
}

/* One line: icon, label, tip glyph, switch. The explanation lives in the
 * lm-tip so this row states WHAT it controls and stays a single line — a
 * three-line caption under the label made a settings row read like a warning,
 * the heaviest thing in a modal whose other rows are one line each. */
.lm-view-insights__row {
    display: flex;
    align-items: center;
    gap: 0.625rem;
}

.lm-view-insights__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    color: var(--bs-primary, #1b84ff);
}

.lm-view-insights__copy {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    /* Takes the slack so the switch pins to the right edge regardless of how
     * the label wraps. */
    flex: 1 1 auto;
    min-width: 0;
}

/* Metronic's own .form-label metrics, matching "View Name" and "Context" two
 * rows up. Only the stacked-field bottom margin is dropped: this label names
 * the switch beside it, not an input underneath it. */
.lm-view-insights__label {
    margin: 0;
    color: var(--bs-gray-800, #252f4a);
    font-size: 1.05rem;
    font-weight: 500;
    line-height: 1.35;
    cursor: pointer;
    text-wrap: pretty;
}

/* .lm-tip inherits its host's type so it reads as part of the label; here that
 * would blow the glyph up to the label's size. Pin it back to a caption size
 * and let it sit on the label's optical centre. */
.lm-view-insights__tip {
    flex: 0 0 auto;
    line-height: 1;
}

.lm-view-insights__tip > i {
    font-size: 0.875rem;
}

.lm-view-insights__switch {
    flex: 0 0 auto;
}
