/*
 * elfrique.components.sidebar.css — Dashboard layout + sidebar primitives
 * Mandate: M04 · C3 Admin Surface · Phase 1
 *
 * Scope: dash-layout, dash-sidebar (all variants), dash-hamburger.
 * Extracted from elfrique.components.layout.css at M04/Phase-1 to respect
 * the ≤1000-line cap on that file.
 *
 * Siblings: elfrique.components.layout.css · elfrique.components.data.css
 *           elfrique.components.overlay.css
 *
 * All styles MUST consume tokens from elfrique.css via var(--token).
 * No raw hex. No raw ms. No Bootstrap class names.
 */


/* ==========================================================================
   DASHBOARD LAYOUT  (Phase 1 · W3.0a–d)
   Fixed-sidebar + fluid-content shell.
   Desktop: 240px sidebar + auto content.
   Tablet 1024px–640px: 56px icon-only rail.
   Mobile <640px: sidebar hidden; offcanvas from header hamburger.
   Source: _Layout.cshtml (picker) + role-specific sidebar partials.
   ========================================================================== */

/* Outer shell — full viewport row below the sticky header */
.dash-layout {
  display:        flex;
  align-items:    stretch;
  min-height:     calc(100vh - 56px); /* 56px = admin-header height */
  font-family:    var(--font-sans);
}

/* Sidebar column — fixed-width host for the <aside> */
.dash-layout__sidebar-col {
  flex:           0 0 240px;
  width:          240px;
  position:       sticky;
  top:            56px;            /* clear the sticky admin header */
  height:         calc(100vh - 56px);
  overflow-y:     auto;
  overflow-x:     hidden;
  scrollbar-width: thin;
  scrollbar-color: var(--n-300) transparent;
}

/* Content area — takes remaining width */
.dash-layout__content {
  flex:           1 1 0;
  min-width:      0;
  padding:        var(--sp-5);
}

/* Sidebar — visual shell */
.dash-sidebar {
  display:          flex;
  flex-direction:   column;
  width:            100%;
  height:           100%;
  background-color: var(--n-50);
  border-right:     1px solid var(--n-200);
}

/* Profile card — condensed: 32px avatar + name only */
.dash-sidebar__profile {
  display:      flex;
  align-items:  center;
  gap:          var(--sp-3);
  padding:      var(--sp-4) var(--sp-4) var(--sp-3);
  border-bottom: 1px solid var(--n-200);
  flex-shrink:  0;
}

.dash-sidebar__avatar {
  flex-shrink:      0;
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  width:            32px;
  height:           32px;
  border-radius:    50%;
  background-color: var(--brand-ink);
  color:            var(--n-0);
  font-family:      var(--font-mono);
  font-size:        var(--fs-1);
  font-weight:      600;
  letter-spacing:   0.04em;
  text-transform:   uppercase;
}

.dash-sidebar__name {
  flex:         1 1 0;
  min-width:    0;
  font-size:    var(--fs-2);
  font-weight:  600;
  color:        var(--brand-ink);
  overflow:     hidden;
  text-overflow: ellipsis;
  white-space:  nowrap;
}

/* Nav area */
.dash-sidebar__nav {
  flex:         1 1 auto;
  overflow-y:   auto;
  padding:      var(--sp-2) 0;
}

/* Nav items — base rules for the .sidebar-nav-item leaf link.
   Custom.css was purged in M19; the kit now owns these rules in full.
   Active state uses --brand-spark token (W3.0b).
   The 40px row height + sp-2*2 padding satisfies ≥44px effective touch target
   because 40 + 8 + 8 = 56px effective height (HR8).
   D1 (M22 Phase 3): color overrides browser-default link-blue cascade from
   user-agent stylesheet; flex + gap fixes icon-to-text spacing.
   D2 (M22 Phase 3): border-left-width + border-left-style are required for
   border-left-color to render; without them the .active border-left-color
   has no visible effect (border defaults to style:none). */
.dash-sidebar .sidebar-nav-item {
  display:           flex;
  align-items:       center;
  gap:               var(--sp-3);
  min-height:        40px;
  padding:           var(--sp-2) var(--sp-4);
  color:             var(--n-700);
  border-left-width: 3px;
  border-left-style: solid;
  border-left-color: transparent;
  transition:        background-color var(--d-1) var(--ease-out-swift),
                     color            var(--d-1) var(--ease-out-swift),
                     border-left-color var(--d-1) var(--ease-out-swift);
}

/* Override: prevent --primary-color (#2E7D32 green) from bleeding in via custom.css L1448.
   Hard rule #1: green is banned as a UI color. */
.dash-sidebar .sidebar-nav-item:hover {
  background-color: var(--n-100);
  color:            var(--brand-ink);
}

.dash-sidebar .sidebar-nav-item:hover i {
  color: var(--brand-ink);
}

.dash-sidebar .sidebar-nav-item.active {
  border-left-color: var(--brand-spark);
  background-color:  color-mix(in srgb, var(--brand-spark) 8%, transparent);
  color:             var(--brand-ink);
  font-weight:       600;
}

.dash-sidebar .sidebar-nav-item.active i {
  color: var(--brand-spark);
}

/* ── Expandable nav groups (M20 phase 5b · F7) ──────────────────────────
   Restores baseline styling for grouped nav after M19 purged custom.css.
   Markup contract (NavBarHelper.cs):
     <div class="sidebar-nav-group [open]">
       <a class="sidebar-nav-item sidebar-nav-toggle"
          aria-expanded="true|false" aria-controls="snav-children-N">
         <i class="mdi mdi-..."></i>
         <span>Label</span>
         <i class="mdi mdi-chevron-down sidebar-nav-caret"></i>
       </a>
       <div class="sidebar-nav-children" id="snav-children-N">
         <a class="sidebar-nav-item sidebar-nav-child [active]">…</a>
       </div>
     </div>
   State: JS toggles `.open` on the group AND aria-expanded on the toggle
   (custom-script.js:663-674). CSS targets `.open` for caret + children.
   ──────────────────────────────────────────────────────────────────────── */

.dash-sidebar .sidebar-nav-group {
  display:       block;
  border-bottom: 1px solid var(--n-200);
}

.dash-sidebar .sidebar-nav-toggle {
  display:         flex;
  align-items:     center;
  justify-content: space-between;
  width:           100%;
  min-height:      44px; /* HR8: explicit touch target on the toggle row */
  cursor:          pointer;
}

.dash-sidebar .sidebar-nav-caret {
  margin-left: auto;
  transform:   rotate(0deg);
  transition:  transform var(--d-2) var(--ease-out-swift);
}

.dash-sidebar .sidebar-nav-group.open .sidebar-nav-toggle .sidebar-nav-caret {
  transform: rotate(180deg);
}

.dash-sidebar .sidebar-nav-children {
  max-height:   0;
  overflow:     hidden;
  padding-left: 0;
  transition:   max-height var(--d-3) var(--ease-out-swift);
}

.dash-sidebar .sidebar-nav-group.open .sidebar-nav-children {
  max-height: 999px; /* large cap; collapses smoothly via the transition */
}

.dash-sidebar .sidebar-nav-child {
  display:         block;
  padding:         var(--sp-2) var(--sp-3) var(--sp-2) var(--sp-6);
  font-size:       var(--fs-2);
  color:           var(--n-700);
  text-decoration: none;
  transition:      background-color var(--d-2) var(--ease-out-swift),
                   color            var(--d-2) var(--ease-out-swift);
}

.dash-sidebar .sidebar-nav-child:hover {
  background-color: var(--n-100);
  color:            var(--brand-ink);
}

.dash-sidebar .sidebar-nav-child.active {
  color:       var(--brand-ink);
  font-weight: 500;
}

/* Section labels — uppercase mono, muted */
.dash-sidebar .sidebar-section-label {
  font-family:    var(--font-mono);
  font-size:      var(--fs-1);
  font-weight:    600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color:          var(--n-400);
  padding:        var(--sp-4) var(--sp-4) var(--sp-2);
}

/* Consumer upgrade CTA */
.dash-sidebar__cta {
  margin:           var(--sp-4);
  padding:          var(--sp-4);
  background-color: var(--n-100);
  border-radius:    var(--r-3);
  border:           1px solid var(--n-200);
}

.dash-sidebar__cta-headline {
  margin:       0 0 var(--sp-1);
  font-family:  var(--font-serif);
  font-size:    var(--fs-3);
  font-weight:  600;
  color:        var(--brand-ink);
}

.dash-sidebar__cta-body {
  margin:      0 0 var(--sp-3);
  font-size:   var(--fs-2);
  color:       var(--n-600);
  line-height: 1.4;
}

/* Offcanvas — inherits desktop sidebar visual treatment */
.dash-sidebar--offcanvas {
  width:            240px !important;
  background-color: var(--n-50);
}

.dash-sidebar__offcanvas-header {
  padding:       var(--sp-4);
  border-bottom: 1px solid var(--n-200);
}

.dash-sidebar__offcanvas-title {
  font-family:  var(--font-sans);
  font-size:    var(--fs-3);
  font-weight:  600;
  color:        var(--brand-ink);
}

.dash-sidebar__offcanvas-close {
  flex-shrink: 0;
}

/* Header hamburger — visible only at <640px */
.dash-hamburger {
  display:          none;
  align-items:      center;
  justify-content:  center;
  min-width:        44px;
  min-height:       44px;
  padding:          0;
  background:       transparent;
  border:           1px solid var(--n-200);
  border-radius:    var(--r-2);
  color:            var(--brand-ink);
  font-size:        var(--fs-5);
  line-height:      1;
  cursor:           pointer;
  transition:       background-color var(--d-1) var(--ease-out-swift),
                    border-color     var(--d-1) var(--ease-out-swift);
}

.dash-hamburger:hover {
  background-color: var(--n-100);
  border-color:     var(--n-300);
}

.dash-hamburger:focus-visible {
  outline:        3px solid var(--state-info);
  outline-offset: 2px;
}

/* ── Responsive: 1024px → icon-only 56px rail ─────────────────────────────
   IMPORTANT: All rules inside this breakpoint MUST be scoped to
   .dash-layout__sidebar-col so they do NOT affect .dash-sidebar--offcanvas.
   Below 640px the hamburger reveals the offcanvas; it must retain its full
   240px layout with labels and name visible.
   ─────────────────────────────────────────────────────────────────────── */

@media (max-width: 1023px) {
  .dash-layout__sidebar-col {
    flex:  0 0 56px;
    width: 56px;
  }

  /* Icon-only rail: hide text labels, center icons — desktop sidebar col only */
  .dash-layout__sidebar-col .dash-sidebar .sidebar-nav-item {
    padding:         var(--sp-3) 0;
    justify-content: center;
    gap:             0;
    min-height:      44px;
  }

  /* Hide text nodes — CSS-only approach: font-size 0 on parent, restore on icon.
     Scoped to sidebar-col so offcanvas retains normal text layout. */
  .dash-layout__sidebar-col .dash-sidebar__nav {
    font-size: 0;
  }

  .dash-layout__sidebar-col .dash-sidebar .sidebar-nav-item i {
    font-size: 20px; /* restore icon size */
    width:     auto;
  }

  /* Hide profile name, section labels, cta, nav-caret in rail mode — desktop col only */
  .dash-layout__sidebar-col .dash-sidebar__name,
  .dash-layout__sidebar-col .dash-sidebar .sidebar-section-label,
  .dash-layout__sidebar-col .dash-sidebar__cta,
  .dash-layout__sidebar-col .dash-sidebar .sidebar-nav-caret,
  .dash-layout__sidebar-col .dash-sidebar .sidebar-nav-children {
    display: none;
  }

  /* Avatar centering in rail — desktop col only */
  .dash-layout__sidebar-col .dash-sidebar__profile {
    justify-content: center;
    padding:         var(--sp-3);
    gap:             0;
  }
}

/* ── Responsive: 640px → offcanvas, hamburger shows ─────────────────────
   M10 Phase 2 W6.4 success criterion: "Never both visible" — at <640px the
   desktop sidebar column is display:none, which makes the collapsed-rail
   state irrelevant by definition. The .dash-layout__sidebar-col--collapsed
   rule below is reinforced with display:none at <640px so the JS-toggled
   collapsed class can never override the offcanvas-only mode.
   ──────────────────────────────────────────────────────────────────────── */

@media (max-width: 639px) {
  /* Hide the desktop sidebar column entirely (collapsed class included). */
  .dash-layout__sidebar-col,
  .dash-layout__sidebar-col--collapsed {
    display: none;
  }

  /* Hamburger becomes visible */
  .dash-hamburger {
    display: inline-flex;
  }

  /* Content takes full width */
  .dash-layout__content {
    padding: var(--sp-4);
  }
}

/* ==========================================================================
   SIDEBAR FOOTER SLOT  (W3.21)
   Version string + /design/kit dev link + collapse toggle chevron.
   ========================================================================== */

.dash-sidebar__footer {
  flex-shrink:    0;
  display:        flex;
  align-items:    center;
  justify-content: space-between;
  gap:            var(--sp-2);
  padding:        var(--sp-3) var(--sp-4);
  border-top:     1px solid var(--n-200);
}

.dash-sidebar__version {
  font-family:  var(--font-mono);
  font-size:    var(--fs-1);
  color:        var(--n-400);
  white-space:  nowrap;
  overflow:     hidden;
  text-overflow: ellipsis;
  flex:         1 1 0;
  min-width:    0;
}

.dash-sidebar__kit-link {
  font-family:  var(--font-mono);
  font-size:    var(--fs-1);
  color:        var(--state-info);
  text-decoration: underline;
  white-space:  nowrap;
  flex-shrink:  0;
}

.dash-sidebar__kit-link:hover {
  color: color-mix(in srgb, var(--state-info) 80%, var(--n-900));
}

/* Collapse toggle button — chevron at footer right */
.dash-sidebar__collapse-toggle {
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  flex-shrink:      0;
  min-width:        44px;
  min-height:       44px;
  padding:          0;
  background:       transparent;
  border:           none;
  border-radius:    var(--r-2);
  color:            var(--n-400);
  font-size:        var(--fs-4);
  line-height:      1;
  cursor:           pointer;
  transition:       color var(--d-1) var(--ease-out-swift),
                    background-color var(--d-1) var(--ease-out-swift);
}

.dash-sidebar__collapse-toggle:hover {
  background-color: var(--n-100);
  color:            var(--brand-ink);
}

.dash-sidebar__collapse-toggle:focus-visible {
  outline:        3px solid var(--state-info);
  outline-offset: 2px;
}

/* Collapsed state — triggered by JS adding class to .dash-layout__sidebar-col */
/* Matches the existing 56px icon-rail from @media (max-width: 1023px) */
.dash-layout__sidebar-col--collapsed {
  flex:  0 0 56px;
  width: 56px;
}

.dash-layout__sidebar-col--collapsed .dash-sidebar .sidebar-nav-item {
  padding:         var(--sp-3) 0;
  justify-content: center;
  gap:             0;
  min-height:      44px;
}

.dash-layout__sidebar-col--collapsed .dash-sidebar__nav {
  font-size: 0;
}

.dash-layout__sidebar-col--collapsed .dash-sidebar .sidebar-nav-item i {
  font-size: 20px;
  width:     auto;
}

.dash-layout__sidebar-col--collapsed .dash-sidebar__name,
.dash-layout__sidebar-col--collapsed .dash-sidebar .sidebar-section-label,
.dash-layout__sidebar-col--collapsed .dash-sidebar__cta,
.dash-layout__sidebar-col--collapsed .dash-sidebar .sidebar-nav-caret,
.dash-layout__sidebar-col--collapsed .dash-sidebar .sidebar-nav-children,
.dash-layout__sidebar-col--collapsed .dash-sidebar__version,
.dash-layout__sidebar-col--collapsed .dash-sidebar__kit-link {
  display: none;
}

.dash-layout__sidebar-col--collapsed .dash-sidebar__profile {
  justify-content: center;
  padding:         var(--sp-3);
  gap:             0;
}

.dash-layout__sidebar-col--collapsed .dash-sidebar__footer {
  justify-content: center;
  padding:         var(--sp-3) 0;
}

/* Rotate chevron when sidebar is collapsed */
.dash-layout__sidebar-col--collapsed .dash-sidebar__collapse-toggle .dash-sidebar__collapse-icon {
  transform: rotate(180deg);
}

.dash-sidebar__collapse-icon {
  transition: transform var(--d-2) var(--ease-out-swift);
}

/* ── Temporary-expand (M27 D9) ─────────────────────────────────────────────
   When a user clicks anywhere on the collapsed icon-only rail (except the
   persisted-collapse caret), JS adds .dash-layout__sidebar-col--temporary-expand
   to the column host. The composite selector
     .dash-layout__sidebar-col--collapsed.dash-layout__sidebar-col--temporary-expand
   re-asserts the expanded geometry without removing the base collapsed class,
   so the dismiss handler can revert by removing the modifier alone. The
   modifier is DOM-only — never persisted to localStorage.

   State-distinction: the temporary-expand carries a subtle left-edge accent
   in --brand-spark and a soft drop-shadow so users can tell at a glance it
   is a transient peek rather than the locked-open persisted state.
   ────────────────────────────────────────────────────────────────────────── */

.dash-layout__sidebar-col--collapsed.dash-layout__sidebar-col--temporary-expand {
  flex:        0 0 240px;
  width:       240px;
  box-shadow:  var(--shadow-3);
  border-left: 3px solid var(--brand-spark);
  transition:  flex-basis var(--d-2) var(--ease-out-swift),
               width      var(--d-2) var(--ease-out-swift),
               box-shadow var(--d-2) var(--ease-out-swift);
}

/* Restore the expanded-state visuals that the collapsed cascade hides. */
.dash-layout__sidebar-col--collapsed.dash-layout__sidebar-col--temporary-expand .dash-sidebar__nav {
  font-size: var(--fs-2);
}

.dash-layout__sidebar-col--collapsed.dash-layout__sidebar-col--temporary-expand .dash-sidebar .sidebar-nav-item {
  padding:         var(--sp-2) var(--sp-4);
  justify-content: flex-start;
  gap:             var(--sp-3);
}

.dash-layout__sidebar-col--collapsed.dash-layout__sidebar-col--temporary-expand .dash-sidebar .sidebar-nav-item i {
  font-size: var(--fs-3);
}

.dash-layout__sidebar-col--collapsed.dash-layout__sidebar-col--temporary-expand .dash-sidebar__name,
.dash-layout__sidebar-col--collapsed.dash-layout__sidebar-col--temporary-expand .dash-sidebar .sidebar-section-label,
.dash-layout__sidebar-col--collapsed.dash-layout__sidebar-col--temporary-expand .dash-sidebar__cta,
.dash-layout__sidebar-col--collapsed.dash-layout__sidebar-col--temporary-expand .dash-sidebar .sidebar-nav-caret,
.dash-layout__sidebar-col--collapsed.dash-layout__sidebar-col--temporary-expand .dash-sidebar__version,
.dash-layout__sidebar-col--collapsed.dash-layout__sidebar-col--temporary-expand .dash-sidebar__kit-link {
  display: revert;
}

.dash-layout__sidebar-col--collapsed.dash-layout__sidebar-col--temporary-expand .dash-sidebar .sidebar-nav-group.open .sidebar-nav-children {
  display: block;
}

.dash-layout__sidebar-col--collapsed.dash-layout__sidebar-col--temporary-expand .dash-sidebar__profile {
  justify-content: flex-start;
  padding:         var(--sp-4) var(--sp-4) var(--sp-3);
  gap:             var(--sp-3);
}

.dash-layout__sidebar-col--collapsed.dash-layout__sidebar-col--temporary-expand .dash-sidebar__footer {
  justify-content: space-between;
  padding:         var(--sp-3) var(--sp-4);
}

/* ── Reduced-motion fallback (CLAUDE.md hard rule #10) ──────────────────
   Disables the collapse/expand chevron and offcanvas slide-in transitions
   for users with reduced-motion preference. Functionality preserved; only
   the motion is removed.
   ──────────────────────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .dash-sidebar .sidebar-nav-item,
  .dash-sidebar .sidebar-nav-child, /* M20 F7 */
  .dash-sidebar .sidebar-nav-children, /* M20 F7 */
  .dash-hamburger,
  .dash-sidebar__collapse-toggle,
  .dash-sidebar__collapse-icon,
  .dash-sidebar--offcanvas,
  .sidebar-nav-caret { /* F-3-03 */
    transition-duration: 0ms;
  }

  /* Sidebar column width transition (collapse animation) — CSS file does
     not currently animate width; declared here so any future width
     transition added at the col level inherits the reduced-motion override.
     M27 D9: temporary-expand modifier animates flex-basis/width/box-shadow;
     reduced-motion zeroes those durations alongside the base column. */
  .dash-layout__sidebar-col,
  .dash-layout__sidebar-col--collapsed,
  .dash-layout__sidebar-col--collapsed.dash-layout__sidebar-col--temporary-expand {
    transition-duration: 0ms;
  }
}
