/* ═══════════════════════════════════════════════════════════════════════════
   nav.css — the admin sidebar: independent scrolling + collapsible categories
   Run 16, F1. Loaded AFTER /admin.css, so the `.sidebar-nav` rule below wins at
   equal specificity (admin.css:130 declares only display/flex-direction/gap —
   nothing here is fighting it, the two are additive).

   Nothing in this file may restyle `.nav-item` itself: every tab must stay
   pixel-identical to before Run 16 (plan §1.3). Category headers are the only
   new visual element.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── F1a: the nav is the only part of the sidebar that scrolls ──
   `.sidebar` stays `position: fixed; top:0; bottom:0` (admin.css:95) and its
   header / actions / footer stay pinned; only this box overflows.
   `min-height: 0` is load-bearing — a flex child's default `min-height: auto`
   refuses to shrink below its content, so without it the nav simply grows past
   the viewport again and nothing scrolls. */
.sidebar-nav {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    /* The drawer must not chain its scroll to the page behind it (phones). */
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    padding-right: 2px;
    scrollbar-width: thin;
    scrollbar-color: rgba(148, 163, 184, 0.35) transparent;
}

.sidebar-nav::-webkit-scrollbar {
    width: 8px;
}

.sidebar-nav::-webkit-scrollbar-track {
    background: transparent;
}

.sidebar-nav::-webkit-scrollbar-thumb {
    background: rgba(148, 163, 184, 0.28);
    border-radius: 999px;
}

.sidebar-nav::-webkit-scrollbar-thumb:hover {
    background: rgba(148, 163, 184, 0.45);
}

/* ── The "Collapse all / Expand all" control (plan §1.3, cut line C6) ──
   Sits in the sidebar header, never inside the scroller. `flex-wrap` on the
   header is a safety net: if the brand + button ever exceed 192px of usable
   width (e.g. the webfont failed to load) the button drops to its own
   right-aligned line instead of squeezing — and clipping — the gradient-clipped
   brand text.
   The 48px bottom margin was pure dead space directly above a list the owner
   cannot reach the bottom of; halving it buys back one row at every viewport. */
.sidebar-header {
    flex-wrap: wrap;
    row-gap: var(--space-xs);
    margin-bottom: var(--space-lg);
}

.nav-all-btn {
    margin-left: auto;
    flex-shrink: 0;
    white-space: nowrap;
    background: none;
    border: 1px solid var(--border-default);
    border-radius: var(--radius-sm);
    padding: 2px 6px;
    color: var(--text-secondary);
    font-family: var(--font-display);
    /* Sized so the LONGER label ("Collapse all") still fits on the brand's line:
       otherwise the header grows a row on collapse and shrinks it again on
       expand — a layout jump every time the control is pressed. */
    font-size: 0.58rem;
    font-weight: 600;
    letter-spacing: 0;
    cursor: pointer;
    transition: color var(--duration-fast) var(--ease-out),
        border-color var(--duration-fast) var(--ease-out);
}

.nav-all-btn:hover {
    color: var(--text-primary);
    border-color: rgba(155, 163, 194, 0.3);
}

.nav-all-btn:focus-visible {
    outline: 2px solid var(--accent-light);
    outline-offset: 2px;
}

/* ── F1b: categories ── */
.nav-cat {
    display: block;
}

/* Zero visible children for this account → the whole category disappears
   (nav.js computes it from the children's LIVE display, never from an area
   list, so it can't disagree with renderSidebarFromAreas()). */
.nav-cat.hidden {
    display: none;
}

.nav-cat-head {
    display: flex;
    align-items: center;
    gap: 6px;
    width: 100%;
    background: none;
    border: none;
    padding: 7px 14px 3px;
    /* Plan §1.5 (BINDING): --text-muted (#636D8C) measures 3.59:1 on the sidebar
       surface and FAILS AA for an 11.2px label. --text-secondary (#9BA3C2)
       measures ~7.4:1 — the harness re-measures it against the RENDERED pixel. */
    color: var(--text-secondary);
    font-family: var(--font-display);
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    text-align: left;
    cursor: pointer;
    transition: color var(--duration-fast) var(--ease-out);
}

.nav-cat-head:hover {
    color: var(--text-primary);
}

.nav-cat-head:focus-visible {
    outline: 2px solid var(--accent-light);
    outline-offset: -2px;
    border-radius: var(--radius-sm);
}

/* Exactly ONE visible child → a disclosure control that reveals one row is pure
   friction, so the category renders as a bare nav item (plan §1.2). */
.nav-cat.bare > .nav-cat-head {
    display: none;
}

.nav-cat-chev {
    flex-shrink: 0;
    transition: transform var(--duration-fast) var(--ease-out);
}

/* A down-chevron rotated -90deg (counter-clockwise) points RIGHT in LTR —
   the same collapsed affordance the dashboard groups use. */
.nav-cat.collapsed .nav-cat-chev {
    transform: rotate(-90deg);
}

.nav-cat-label {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Rolled-up count while the category is collapsed (plan §1.6). Inherits
   .nav-badge's pill styling from admin.css:2194. */
.nav-cat-badge {
    margin-left: auto;
    flex-shrink: 0;
}

.nav-cat-body {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
}

/* ── Notifications + Logout: pinned below the scroller (plan §1.1, C7) ──
   The owner's complaint is literally "hard to reach the bottom", and Logout IS
   the bottom item. Keeping them out of the scroll area also removes two rows
   from it. Ids and the .nav-item class are unchanged, so every existing
   listener (#navNotify, #logoutBtn, initPushUI's #notifyLabel) still binds. */
.sidebar-actions {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    flex-shrink: 0;
    margin-top: var(--space-sm);
    padding-top: var(--space-sm);
    border-top: 1px solid var(--border-default);
}

/* ── "there is more below" ──
   macOS and iOS both use OVERLAY scrollbars: nothing is painted until you
   already scroll, so a clipped list can read as a list that simply ENDS — which
   is the owner's original complaint restated. A fade over the last rows says
   "keep going" at every viewport, including the iPhone PWA where no scrollbar
   can ever be shown. nav.js toggles `nav-more-below` on the scroller from its
   real scroll position; the fade paints on the pinned actions block, so it can
   never scroll away. rgb(16,22,37) is the MEASURED sidebar surface. */
.sidebar-nav.nav-more-below+.sidebar-actions::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 100%;
    height: 26px;
    pointer-events: none;
    background: linear-gradient(to bottom, rgba(16, 22, 37, 0), rgba(16, 22, 37, 0.92));
}
