/* R-06b contextual sidebar. Scales: spacing 4/8/12/16/24/32; type 11/13/15;
   one accent; no gradients; every row >= 44px. */
#kt_app_sidebar.app-sidebar{background:#0f1320 !important;border-right:1px solid rgba(255,255,255,.06) !important;}
#kt_app_sidebar #kt_app_sidebar_logo{background:transparent !important;border-bottom:1px solid rgba(255,255,255,.06) !important;}
#kvNav{
  --kvn-1:4px; --kvn-2:8px; --kvn-3:12px; --kvn-4:16px; --kvn-6:24px; --kvn-8:32px;
  --kvn-fs-micro:11px; --kvn-fs-small:13px; --kvn-fs-body:15px;
  --kvn-accent:#6d4bf0;
  --kvn-ink:#eef1f8; --kvn-text:#ccd3e4; --kvn-meta:#98a1b8;
  --kvn-hover:rgba(255,255,255,.06);
  --kvn-row:44px;
  display:block; padding:var(--kvn-2) var(--kvn-3) var(--kvn-8);
  font-size:var(--kvn-fs-body); line-height:1.3;
}
#kvNav *,#kvNav *::before,#kvNav *::after{box-sizing:border-box;}
#kvNav details{margin:0;}
#kvNav summary{list-style:none; cursor:pointer;}
#kvNav summary::-webkit-details-marker{display:none;}
#kvNav summary::marker{content:'';}

#kvNav .kvn-row{
  display:flex; align-items:center; gap:var(--kvn-3);
  min-height:var(--kvn-row); padding:var(--kvn-2) var(--kvn-3);
  margin:0 0 var(--kvn-1); border-radius:8px;
  color:var(--kvn-text); text-decoration:none;
  font-weight:500; letter-spacing:.005em;
  -webkit-tap-highlight-color:transparent;
}
#kvNav .kvn-row:hover,#kvNav .kvn-row:focus-visible{background:var(--kvn-hover); color:var(--kvn-ink);}
#kvNav .kvn-row:focus-visible{outline:2px solid var(--kvn-accent); outline-offset:2px;}
#kvNav .kvn-label{flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
#kvNav .kvn-ico{flex:0 0 22px; width:22px; text-align:center; color:var(--kvn-meta); font-size:var(--kvn-fs-body);}
#kvNav .kvn-row:hover .kvn-ico,#kvNav .kvn-active .kvn-ico{color:var(--kvn-ink);}
#kvNav .kvn-dot{flex:0 0 6px; width:6px; height:6px; margin-left:var(--kvn-2); border-radius:50%; background:currentColor; opacity:.35;}

/* INDENTATION LADDER (R-06f, 2026-09-03)
   The founder, on the live ten-door sidebar: "indention padding from parent is worst". The cause
   was structural, not cosmetic. Indentation came from the ROW — .kvn-l2 carried padding-left and
   .kvn-l3 / .kvn-l4 carried NONE — so levels three and four sat at exactly the same x-position as
   level two. Nothing below the second level stepped in at all. Under sidebar_flat_v4, which
   collapses an entire door into ONE .kvn-sub, every row and caption in that door shared a single
   indent: a tree rendered as a flat list.

   Indentation is now owned by the CONTAINER, so it compounds automatically with DOM nesting — one
   step per level, however deep the tree goes, with no per-level rule for a future level to forget.
   Each level also draws its own guide rail, which is what makes a child read as BELONGING to the
   row above rather than merely sitting under it.

   The step is 16px rather than 12px: at 12px the rail collided with the parent's 22px icon column
   and the eye could not separate two adjacent levels. Rails fade as they deepen so the outermost
   stays dominant and the sidebar does not become a ladder of identical lines. */
#kvNav .kvn-l1{font-size:var(--kvn-fs-body);}
#kvNav .kvn-l2{font-size:var(--kvn-fs-body);}
#kvNav .kvn-l3{font-size:var(--kvn-fs-small);}
#kvNav .kvn-l4{font-size:var(--kvn-fs-small); color:var(--kvn-meta);}
#kvNav .kvn-l4:hover{color:var(--kvn-ink);}

#kvNav .kvn-sub{
  margin:var(--kvn-1) 0 var(--kvn-2) var(--kvn-3);
  padding-left:var(--kvn-4);
  border-left:1px solid rgba(255,255,255,.14);
}
#kvNav .kvn-sub .kvn-sub{border-left-color:rgba(255,255,255,.10);}
#kvNav .kvn-sub .kvn-sub .kvn-sub{border-left-color:rgba(255,255,255,.07);}

/* A nested disclosure is a PARENT, so it keeps full-strength text. The old rule greyed level 3
   out, which made a row that opens further rows look less important than its own children. */
#kvNav .kvn-sub details > .kvn-sum{color:var(--kvn-text);}
#kvNav .kvn-sub details[open] > .kvn-sum{color:var(--kvn-ink); font-weight:600;}

/* active page: the one accent, plus a bar so it reads without colour alone */
#kvNav .kvn-active{
  background:rgba(109,75,240,.22); color:#fff; font-weight:600;
  box-shadow:inset 3px 0 0 0 var(--kvn-accent);
}
#kvNav .kvn-active .kvn-dot{opacity:1;}

/* disclosure chevron — CSS only, driven by [open] */
#kvNav .kvn-chev{
  flex:0 0 10px; width:10px; height:10px; margin-left:var(--kvn-2);
  border-right:2px solid currentColor; border-bottom:2px solid currentColor;
  transform:rotate(-45deg); opacity:.5; transition:transform .15s ease;
}
#kvNav details[open] > .kvn-sum > .kvn-chev{transform:rotate(45deg); opacity:.9;}
#kvNav details[open] > .kvn-sum{color:var(--kvn-ink);}

/* "in this module" marker on the auto-opened section */
#kvNav .kvn-here > .kvn-sum .kvn-label::after{
  content:''; display:inline-block; width:6px; height:6px; margin-left:var(--kvn-2);
  border-radius:50%; background:var(--kvn-accent); vertical-align:middle;
}

/* section caption */
#kvNav .kvn-cap{
  margin:var(--kvn-4) var(--kvn-3) var(--kvn-2);
  font-size:var(--kvn-fs-micro); font-weight:700; letter-spacing:.12em;
  text-transform:uppercase; color:var(--kvn-meta);
}
#kvNav .kvn-rule{height:1px; margin:var(--kvn-3) var(--kvn-3); background:rgba(255,255,255,.08);}

/* Unread badge — accent fill. Text is WHITE, computed not assumed: on this
   purple (#6d4bf0) white is 5.36:1 (AA pass) and the dashboard's dark ink
   #11151f is only 3.40:1 (AA fail at this 11px weight). The dashboard flipped
   the other way because its accent sat on a LIGHT surface; this sidebar is
   #0f1320, so the correct answer is the opposite one. */
#kvNav .kvn-badge{
  flex:0 0 auto; min-width:20px; padding:0 6px; height:20px; line-height:20px;
  border-radius:10px; background:var(--kvn-accent); color:#ffffff;
  font-size:var(--kvn-fs-micro); font-weight:700; text-align:center;
}

/* The founder's sentence, implemented literally: "selecting a module expands
   ONLY that module's navigation". Once one module (or one account group) is
   open, its twenty peers step out of the way instead of sitting underneath it
   as twenty more equal choices. Closing it brings the list straight back.
   .kvn-more ("All modules" / "More") is deliberately excluded so the way back
   to the rest is never the thing that disappears.
   Pure CSS, and :has() failing simply leaves every peer visible — the old,
   still-usable behaviour. */
@supports selector(:has(*)){
  #kvNav .kvn-sub:has(> details.kvn-mod[open]) > details.kvn-mod:not([open]){display:none;}
}

/* "More in …" — a quieter row so level 4 never competes with level 3 */
#kvNav .kvn-more > .kvn-sum{color:var(--kvn-meta); font-size:var(--kvn-fs-small); font-weight:600;}
#kvNav .kvn-more > .kvn-sum:hover{color:var(--kvn-ink);}

/* desktop icon-only (Metronic sidebar minimize) — labels off, icons centred */
body[data-kt-app-sidebar-minimize="on"] #kvNav .kvn-label,
body[data-kt-app-sidebar-minimize="on"] #kvNav .kvn-chev,
body[data-kt-app-sidebar-minimize="on"] #kvNav .kvn-cap,
body[data-kt-app-sidebar-minimize="on"] #kvNav .kvn-sub{display:none !important;}
body[data-kt-app-sidebar-minimize="on"] #kvNav .kvn-row{justify-content:center; padding-left:0; padding-right:0;}

@media (prefers-reduced-motion: reduce){#kvNav .kvn-chev{transition:none;}}

/* -------------------------------------------------------------------------
   MOBILE DRAWER GEOMETRY.
   Ported from the block that lived inside _sidebar_navigate_auth.php. It is
   load-bearing and was written against measurements on a real device:
   Metronic's own .drawer class parks the panel at translateX(-100%), and this
   site opens it with body.kv-sidebar-open (NOT Metronic's .drawer-on), so
   without these rules the overlay appears and the panel never arrives.
   Verified by elementFromPoint at 375x812: with the drawer open every row
   returns itself; with it closed no row returns anything.

   `bottom` comes from the shared chrome contract in kv_bottomnav_safe.css so
   the drawer ENDS above the bottom navigation — at bottom:0 its last items sat
   underneath the 76px nav and could not be tapped.
   ---------------------------------------------------------------------- */
@media (max-width: 991.98px){
  #kt_app_sidebar{
    position:fixed !important;
    top:calc(var(--kv-topbar-h, 58px) + env(safe-area-inset-top, 0px)) !important;
    bottom:var(--kv-bottomnav-safe, 0px) !important;
    left:0 !important;
    height:auto !important;
    max-height:calc(100dvh - var(--kv-topbar-h, 58px) - env(safe-area-inset-top, 0px) - var(--kv-bottomnav-safe, 0px)) !important;
    width:min(88vw, 320px) !important;
    display:flex !important; flex-direction:column !important;
    overflow-x:hidden !important; overflow-y:auto !important;
    -webkit-overflow-scrolling:touch !important;
    overscroll-behavior-y:contain;
    z-index:2147483190 !important;
  }
  /* CLOSED. Three independent guarantees, so no single failure can leave an
     invisible panel eating taps: off-screen, visibility:hidden, AND
     pointer-events:none. Nothing here waits on an animation. */
  body:not(.kv-sidebar-open) #kt_app_sidebar{
    transform:translateX(-100%) !important;
    visibility:hidden !important;
    pointer-events:none !important;
    transition:none !important;
  }
  /* OPEN. Deliberately NOT transitioned.
     The old sidebar slid in with `transition: transform .25s ease`. Measured
     here with document.getAnimations(): the CSSTransition on `transform` was
     observed `playState:"running"` with `currentTime: 0` — stuck — leaving the
     panel at translateX(-100%) while the body already carried .kv-sidebar-open,
     so `visibility:visible`, `pointer-events:auto` and the full-screen overlay
     were all live with the menu off-screen. That state locks the member out of
     the menu AND the page behind the overlay, and it cannot be overridden: a
     running animation outranks even an inline `!important` (verified — forcing
     `transform:translateX(0)!important` inline did not move it).
     This is the same failure shape as the welcome-overlay click-trap fixed on
     2026-08-05 (opacity supplied only by a keyframe animation stuck at
     currentTime 0). A 250 ms slide is not worth a lock-out, so the open
     position is now applied instantly and depends on nothing. */
  body.kv-sidebar-open #kt_app_sidebar{
    transform:none !important;
    visibility:visible !important;
    pointer-events:auto !important;
    transition:none !important;
    animation:none !important;
  }
  /* One scroll container on mobile: Metronic's inner flex wrappers are
     flex-shrink:0 and otherwise stop the chain from bounding. */
  #kt_app_sidebar .app-sidebar-menu,
  #kt_app_sidebar_menu_wrapper,
  #kt_app_sidebar_menu_scroll{
    height:auto !important; max-height:none !important; min-height:0 !important;
    overflow:visible !important; flex:0 0 auto !important;
  }
  #kt_app_sidebar_menu_scroll{padding-bottom:calc(28px + env(safe-area-inset-bottom, 0px));}
}
