/* ============================================================
   App rail — a slim, persistent module-switching strip fixed to
   the left of the viewport, positioned BESIDE the existing
   .sidenav-menu (not inside it). Scales cleanly as modules are
   added beyond EVP / Cash Management / RIMS.

   This file is loaded after app.min.css (see _HeadCSS.cshtml) so
   its rules win the cascade for equal-specificity selectors; where
   a rule below repeats one of the theme's own [data-sidenav-size=…]
   selectors verbatim, that is intentional — it lets this override
   "shift" the theme's existing width/margin math by --app-rail-width
   without editing the vendor stylesheet.

   Covers every sidenav mode reachable from this app's Customizer:
   default (no attribute), condensed, compact, sm-hover, full
   (mobile/tablet drawer, auto-applied by app.js below 1140px),
   fullscreen. [data-layout=topnav] is not wired into this app
   (_VerticalLayout is the only layout in use) but the theme's own
   :not([data-layout=topnav]) guard is mirrored below for parity. */

:root {
    --app-rail-width: 56px;
    /* the theme's own --highdmin-topbar-user-border (#eef2f7 light) is too
       faint to read as a divider; use a deliberately visible line instead,
       shared by both dividers (rail | sidebar, sidebar | content) so they
       match exactly. */
    --app-rail-divider: rgba(15, 23, 42, 0.16);
}

html[data-bs-theme=dark] {
    --app-rail-divider: rgba(255, 255, 255, 0.18);
}

/* ---- the rail itself ---- */
.app-rail {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    width: var(--app-rail-width);
    z-index: 1001; /* above .sidenav-menu (1000), below Bootstrap dropdowns/modals (1050+) */
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    padding: 0.625rem 0;
    background: var(--highdmin-menu-bg);
    border-right: 1px solid var(--app-rail-divider);
}

/* the theme ships this at "0 solid" (no visible seam between sidebar and
   content); give it the same 1px divider as the rail so both lines match */
.sidenav-menu {
    border-right: 1px solid var(--app-rail-divider);
}

.app-rail-brand {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    flex-shrink: 0;
    border-radius: 0.5rem;
    margin-bottom: 0.25rem;
    background: linear-gradient(135deg, var(--bs-primary, #777edd), var(--bs-secondary, #02c0ce));
    color: #fff;
    font-weight: 700;
    font-size: 1.2rem;
    text-decoration: none;
}

.app-rail-brand:hover {
    color: #fff;
    opacity: .9;
}

.app-rail-tiles {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    flex: 1 1 auto;
    overflow-y: auto;
    overflow-x: hidden;
    /* Without this, Chrome's scroll anchoring nudges scrollTop on the reflow
       that browser zoom triggers (the app-level `zoom` rules in
       _HeadCSS.cshtml flip at certain viewport widths), silently scrolling
       the first tile out of view even though there's no user-initiated
       scroll. */
    overflow-anchor: none;
}

.app-rail-tile {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    flex-shrink: 0;
    border: none;
    border-radius: 0.625rem;
    background: transparent;
    padding: 0;
    cursor: pointer;
    transition: background-color .15s ease;
}

.app-rail-tile:hover {
    background: var(--highdmin-menu-item-hover-bg, rgba(119, 126, 221, .08));
}

.app-rail-tile.active {
    background: rgba(119, 126, 221, .14);
}

/* left indicator bar signalling the active module, matching the app's active-nav accent */
.app-rail-tile.active::before {
    content: "";
    position: absolute;
    left: -4px;
    top: 50%;
    transform: translateY(-50%);
    width: 3px;
    height: 22px;
    border-radius: 2px;
    background: var(--bs-primary, #777edd);
}

.app-rail-ico {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 0.5rem;
    color: #fff;
    font-size: 1.05rem;
    transition: transform .15s ease, filter .15s ease, opacity .15s ease;
}

/* module tiles show a 2-letter abbreviation (see GetModuleInitials in
   Default.cshtml), not an icon glyph — sized/weighted for legible text
   instead of an icon font. Excludes the launcher tile, which still uses
   an icon and inherits the base .app-rail-ico font-size above. */
.app-rail-tile:not(.app-rail-launcher) .app-rail-ico {
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: .01em;
    font-family: var(--bs-body-font-family, inherit);
}

.app-rail-tile:not(.active) .app-rail-ico {
    filter: grayscale(.5);
    opacity: .62;
}

.app-rail-tile:hover .app-rail-ico {
    opacity: 1;
    filter: none;
}

.app-rail-tile.active .app-rail-ico {
    opacity: 1;
    filter: none;
}

.app-ico-evp { background: linear-gradient(135deg, var(--bs-secondary, #02c0ce), #05a3af); }
.app-ico-cash_recon { background: linear-gradient(135deg, #0acf97, #08a97a); }
.app-ico-rims { background: linear-gradient(135deg, var(--bs-primary, #777edd), #5d63c4); }
.app-ico-p2a { background: linear-gradient(135deg, #f59e0b, #d97706); }
.app-ico-apr { background: linear-gradient(135deg, #00758f, #0b3b4a); }
.app-ico-arr { background: linear-gradient(135deg, #7c5cd6, #4a3aa7); }
.app-ico-default { background: linear-gradient(135deg, #9ba6b7, #7c8797); }

.app-rail-launcher .app-rail-ico {
    background: transparent;
    border: 1.5px dashed var(--bs-border-color, #ced4da);
    color: var(--highdmin-menu-item-color);
    filter: none;
    opacity: 1;
}

.app-rail-launcher:hover .app-rail-ico {
    border-style: solid;
    border-color: var(--bs-primary, #777edd);
    color: var(--bs-primary, #777edd);
    transform: translateY(-1px);
}

/* ---- shift the existing sidenav / topbar / page-content over by the rail's width ----
   Selectors below are repeated verbatim from app.min.css per sidenav mode so this
   file's later cascade position — not specificity tricks — decides the winner.

   Every rule is scoped with .wrapper:has(.app-rail) so the offset only ever
   applies when the rail actually rendered. Single-module roles (e.g. supplier
   accounts) never get the rail — Default.cshtml only renders it when
   showModuleSwitcher is true — so without this guard the sidebar/topbar/
   content would still shift right by --app-rail-width and leave a dead gutter
   with nothing filling it. :has() is used instead of a sibling combinator
   because .app-rail renders after .app-topbar in the DOM (sibling selectors
   only match forward), so a plain ~ combinator can't reach .app-topbar. */
html:not([data-layout=topnav]) .wrapper:has(.app-rail) .sidenav-menu {
    left: var(--app-rail-width);
}

html:not([data-layout=topnav]) .wrapper:has(.app-rail) .page-content,
html:not([data-layout=topnav]) .wrapper:has(.app-rail) .app-topbar {
    margin-left: calc(var(--highdmin-sidenav-width) + var(--app-rail-width));
}

html[data-sidenav-size=condensed]:not([data-layout=topnav]) .wrapper:has(.app-rail) .page-content {
    margin-left: calc(var(--highdmin-sidenav-width-sm) + var(--app-rail-width));
}

html[data-sidenav-size=condensed]:not([data-layout=topnav]) .wrapper:has(.app-rail) .app-topbar {
    margin-left: calc(var(--highdmin-sidenav-width-sm) + var(--app-rail-width));
}

html[data-sidenav-size=compact]:not([data-layout=topnav]) .wrapper:has(.app-rail) .page-content,
html[data-sidenav-size=compact]:not([data-layout=topnav]) .wrapper:has(.app-rail) .app-topbar {
    margin-left: calc(var(--highdmin-sidenav-width-md) + var(--app-rail-width));
}

html[data-sidenav-size=sm-hover]:not([data-layout=topnav]) .wrapper:has(.app-rail) .page-content,
html[data-sidenav-size=sm-hover]:not([data-layout=topnav]) .wrapper:has(.app-rail) .app-topbar {
    margin-left: calc(var(--highdmin-sidenav-width-sm) + var(--app-rail-width));
}

/* ---- full (mobile/tablet drawer, auto-applied by app.js below 1140px) and
   fullscreen (zen-mode toggle) hide the sidebar off-canvas; the rail steps
   aside too so the drawer/full-width content isn't left with a dead gutter ---- */
html[data-sidenav-size=full] .app-rail,
html[data-sidenav-size=fullscreen] .app-rail {
    display: none;
}

html[data-sidenav-size=full]:not([data-layout=topnav]) .sidenav-menu,
html[data-sidenav-size=fullscreen]:not([data-layout=topnav]) .sidenav-menu {
    left: 0;
}

/* the unqualified margin-left rule above (page-content/app-topbar shifted by
   sidenav+rail width) has no [data-sidenav-size=full/fullscreen] exception,
   so without this it keeps shoving content/topbar right even after the rail
   and sidenav go off-canvas, leaving a dead gutter with the hamburger button
   stranded in it — visible as the "sidebar goes blank" glitch when browser
   zoom crosses the app.js 1140px mobile-drawer breakpoint. */
html[data-sidenav-size=full]:not([data-layout=topnav]) .wrapper:has(.app-rail) .page-content,
html[data-sidenav-size=full]:not([data-layout=topnav]) .wrapper:has(.app-rail) .app-topbar,
html[data-sidenav-size=fullscreen]:not([data-layout=topnav]) .wrapper:has(.app-rail) .page-content,
html[data-sidenav-size=fullscreen]:not([data-layout=topnav]) .wrapper:has(.app-rail) .app-topbar {
    margin-left: 0;
}

/* the module launcher modal's own content (search box, cards) mirrors the
   app's Bootstrap tokens so it matches light/dark automatically */
.module-launcher-search {
    position: relative;
}

.module-launcher-search i {
    position: absolute;
    left: 0.75rem;
    top: 50%;
    transform: translateY(-50%);
    color: var(--bs-secondary-color, #9ba6b7);
    font-size: 1rem;
    pointer-events: none;
}

.module-launcher-search .form-control {
    padding-left: 2.25rem;
}

.module-launcher-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 0.75rem;
}

.module-launcher-card {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    width: 100%;
    text-align: left;
    padding: 0.875rem;
    border: 1px solid var(--bs-border-color, #e9edf2);
    border-radius: 0.625rem;
    background: var(--bs-body-bg, #fff);
    cursor: pointer;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.module-launcher-card:hover {
    border-color: var(--bs-primary, #777edd);
    box-shadow: 0 2px 10px rgba(0, 0, 0, .06);
}

.module-launcher-card.current {
    border-color: var(--bs-primary, #777edd);
    background: rgba(var(--bs-primary-rgb, 119, 126, 221), .06);
}

.module-launcher-card.d-none-force {
    display: none !important;
}

.module-launcher-ico {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    border-radius: 0.5rem;
    color: #fff;
    font-size: 1.15rem;
}

.module-launcher-copy {
    min-width: 0;
}

.module-launcher-name {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.9375rem;
    font-weight: 600;
    color: var(--bs-body-color);
}

.module-launcher-desc {
    display: block;
    margin-top: 0.15rem;
    font-size: 0.8125rem;
    color: var(--bs-secondary-color, #9ba6b7);
    line-height: 1.4;
}
