/* ============================================================
   DESIGN-SYSTEM REFACTOR - layout primitives (Phase 2).
   Spacing is owned by the container via gap; children carry no
   outer margin. These replace the margin utilities (mt and mb)
   and the duplicate flex/display families. Column modifiers use
   the -cols- name to avoid colliding with the legacy .grid-2
   utility (migrated + deleted in Phase 4/5).
   ============================================================ */
/* Layout primitives - the ONLY way to space siblings. Each owns its gap; its
   children carry no outer margin. 12px (--sp-3) is the standard rhythm; 8px
   (--sp-2) for tight/inline groups. */
.stack { display: flex; flex-direction: column; gap: var(--sp-3); }
.stack-tight { display: flex; flex-direction: column; gap: var(--sp-2); }
.cluster     { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
/* A <fieldset> used purely to give a button cluster a group label (no form chrome). */
.gallery-fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
.grid        { display: grid; gap: var(--sp-3); }
.grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cluster-between { justify-content: space-between; }
.cluster-end     { justify-content: flex-end; }
.is-hidden       { display: none !important; }

.sidebar {
    width: var(--nav-w);
    background: var(--nav-surface);
    color: var(--nav-text);
    padding: var(--sp-4);
    display: flex;
    flex-direction: column;
    position: fixed;
    height: 100vh;
    transition: var(--transition-layout);
    z-index: 100;
    border-right: 1px solid var(--nav-border);
    overflow-x: hidden;
}

.sidebar.collapsed {
    width: var(--nav-w-collapsed);
    padding: var(--sp-4) var(--sp-2);
}

.sidebar.collapsed .nav-section-label,
.sidebar.collapsed .nav-link span,
.sidebar.collapsed .brand span,
.sidebar.collapsed .nav-section-header .chevron {
    display: none;
}

.sidebar.collapsed .brand {
    justify-content: center;
}

/* Hide navigation section headers entirely when collapsed */
.sidebar.collapsed .nav-section-header {
    display: none !important;
}

/* Force show and flatten collapsible contents when collapsed */
.sidebar.collapsed .nav-collapsible .nav-section-content {
    display: flex !important;
    padding-left: 0;
    margin-bottom: var(--sp-4);
    gap: var(--sp-1);
}

/* Center-align collapsed nav-links and active background glow */
.sidebar.collapsed .nav-link {
    justify-content: center;
    padding: var(--sp-2) 0;
    margin-bottom: var(--sp-1);
}

/* Center-align spacers */
.sidebar.collapsed .nav-section-spacer {
    height: var(--sp-4);
}


.sidebar-nav-container {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: var(--sp-1);
}
.sidebar-footer-form {
    margin-top: auto;
    padding-top: var(--sp-4);
    border-top: 1px solid var(--nav-border);
}
.nav-link-action-folder {
    margin-top: auto;
    border-top: 1px solid var(--nav-border);
    padding-top: var(--sp-4);
}
.sidebar-logout-btn {
    width: 100%;
    text-align: left;
    background: none;
    border: none;
    cursor: pointer;
    color: var(--danger);
}

/* Collapsed/rail: hide the brand name, keep the logo (the brand row stays
   clickable to expand — no separate toggle-arrow affordance). */
.sidebar.collapsed .brand-name-row {
    display: none !important;
}

/* One empty row between the brand and the nav (both states). The sidebar brand drops
   its own bottom margin so the spacer is exactly one clean row of breathing space and
   the logo never crowds the first nav item. */
.sidebar > .brand { margin-bottom: 0; }
.brand-spacer { height: var(--row-h); flex-shrink: 0; }

.main {
    padding: var(--sp-4);
    margin-left: var(--nav-w);
    width: calc(100% - var(--nav-w));
    transition: var(--transition-layout);
    min-width: 0;
    /* Page is a vertical stack: ONE mechanism (gap) owns the rhythm between
       sections (top-bar, search, cards). Children carry no outer margin — same
       rule as .stack. 12px = the standard between-sibling step (--sp-3). */
    display: flex;
    flex-direction: column;
    gap: var(--sp-3);
}

.main.expanded {
    margin-left: var(--nav-w-collapsed);
    width: calc(100% - var(--nav-w-collapsed));
}

.nav-link {
    display: flex;
    align-items: center;
    gap: var(--sp-4);
    padding: var(--sp-1) var(--sp-3);
    color: var(--nav-text);
    text-decoration: none;
    border-radius: var(--radius-control);
    margin-bottom: var(--sp-1);
    transition: var(--transition);
    font-size: var(--fs-2);
    font-weight: var(--fw-500);
    opacity: 0.7;
}
.nav-link:hover { background: var(--nav-hover); opacity: 1; }
.nav-link.active { background: var(--nav-active); color: var(--nav-text); opacity: 1; font-weight: var(--fw-600); box-shadow: var(--sh-3); border: none; }
/* .nav-link is a dual-purpose component: an <a> for navigation and a <button> for
   actions (New Folder, Upload, Logout). Reset native button chrome so they match. */
button.nav-link { width: 100%; text-align: left; background: none; border: none; cursor: pointer; font-family: inherit; }

.top-bar { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); }
/* Heading sits in a gap-container (.main); its own margin would double the rhythm. */
.top-bar h1, .top-bar h2 { margin: 0; }

@keyframes slideUp { from { bottom: -100px; opacity: 0; } to { bottom: var(--sp-5); opacity: 1; } }

.main.no-sidebar {
    width: 100%;
    max-width: 800px;
    margin: 0 auto; /* centers within max-width; the old margin-left:0 was dead (overridden) */
    padding: var(--sp-5) var(--sp-4);
}

/* Collapsible Sidebar Sections */
.nav-section-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--sp-1) var(--sp-3);
    color: var(--nav-text);
    cursor: pointer;
    border-radius: var(--radius-control);
    transition: var(--transition);
    opacity: 0.8;
    margin-bottom: var(--sp-1);
    user-select: none;
}
.nav-section-header:hover { background: var(--nav-hover); opacity: 1; }
.nav-section-header .chevron { transition: transform 0.3s ease; opacity: 0.5; }

.nav-collapsible .nav-section-content {
    display: none;
    flex-direction: column;
    gap: var(--sp-1);
    padding-left: var(--sp-4);
    margin-bottom: var(--sp-4);
}
.nav-collapsible.expanded .nav-section-content { display: flex; }
.nav-collapsible.expanded .chevron { transform: rotate(180deg); }

.nav-section-label { font-size: var(--fs-1); font-weight: var(--fw-600); text-transform: uppercase; letter-spacing: 0.05em; }

/* Floating mobile nav opener — a canonical .btn .btn-icon (the brand logo IS
   its icon). This class adds ONLY what the icon button can't: fixed position +
   the nav-chrome surface (so it's visible/tappable over page content). Hidden
   on desktop; shown ≤640px. Geometry/radius/centering all come from .btn-icon.
   Selector is button-scoped so `display:none` outranks .btn's own display. */
button.nav-toggle {
    display: none;
    position: fixed;
    top: var(--sp-4);
    left: var(--sp-4);
    z-index: 110;
    background: var(--nav-surface);
    color: var(--nav-text);
    border-color: var(--nav-border);
    box-shadow: var(--sh-2);
}

/* Mobile: when the drawer is open, hide the floating logo toggle — the open
   drawer's own brand (logo + name) becomes the close control. */
body.nav-open .nav-toggle { display: none; }

/* Hard guarantee: the floating logo toggle is a MOBILE-ONLY affordance. Above the
   mobile breakpoint it must never show (it was leaking over the rail/expanded
   sidebar). !important + the body-scoped selector beat any .btn display rule. */
@media (min-width: 641px) {
    body button.nav-toggle { display: none !important; }
}

/* Collapse is CLASS-DRIVEN at every width (.sidebar.collapsed + .main.expanded)
   so the logo/brand click toggles it in ANY tier. JS (applyResponsiveNav in
   layout.html) sets the per-tier DEFAULT: wide (>1100) = expanded, mid
   (641–1100) = collapsed rail, mobile (≤640) = off-canvas + full drawer. */

/* ── True mobile: sidebar goes off-canvas, toggled by the hamburger (which
   stays visible to also close). The drawer opens FULL (JS removes .collapsed). */
@media (max-width: 640px) {
    .sidebar {
        transform: translateX(-100%);
        box-shadow: var(--sh-3);
    }
    .sidebar.open { transform: translateX(0); }
    .main, .main.expanded {
        margin-left: 0;
        width: 100%;
        padding-top: calc(var(--sp-5) + var(--sp-5));
    }
    button.nav-toggle { display: inline-flex; }
}

/* Defensive scroll: ensure html/body never trap content under viewport height */
html, body { overflow-x: hidden; }
body { overflow-y: auto; }
