/* App shell: sidebar + (header + content) column. */

.app {
    display: grid;
    grid-template-columns: var(--sidebar-width) 1fr;
    min-height: 100vh;
    transition: grid-template-columns var(--motion-fast) var(--easing);
}

/* Compact by design, not by scroll: the full nav list (ten top-level items
   plus Leads plus, for a platform admin, Admin panel and Logout) has to fit
   in `100vh` with no internal scroll region, because a scrolling nav traded
   away the new-violations tooltip's ability to escape the sidebar's right
   edge (an `overflow-y` other than `visible` forces `overflow-x` to behave
   the same way) and, worse, could visually separate Logout from its real
   position in the list. `--nav-item-height`, the sidebar's own padding, and
   the org box/separator spacing below are all tuned down from their
   original values for exactly this reason — see the "Sidebar navigation"
   section of this README for the full item-by-item budget. Typography stays
   at the design-specified sizes throughout; only spacing shrank. */
.app__sidebar {
    background: var(--color-surface);
    border-right: 1px solid var(--color-border);
    padding: var(--space-4);
    position: sticky;
    top: 0;
    height: 100vh;
    overflow: visible;
    z-index: var(--z-sidebar);
    display: flex;
    flex-direction: column;
}

.sidebar-footer {
    margin-top: auto;
}

.app__sidebar-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    padding: 0 var(--space-2) var(--space-3);
}

.app__sidebar-title {
    font-size: var(--fs-base);
    line-height: 150%;
    font-weight: var(--fw-medium);
    color: var(--color-fg-strong);
    white-space: nowrap;
    overflow: hidden;
}

.sidebar-toggle {
    flex-shrink: 0;
    color: var(--color-fg-muted);
}

.sidebar-toggle .icon {
    width: 16px;
    height: 16px;
    transition: transform var(--motion-fast) var(--easing);
}

/* ─── Collapsed sidebar (icon-only) ───────────────────────────────────────
   Toggled by `[data-sidebar-toggle]` in app.js, which flips this class on
   `<html>` and remembers the choice in localStorage. The same class is
   applied synchronously in `base.html`'s `<head>` (before the sidebar even
   paints) so a returning visitor never sees the expanded state flash first. */

:root.sidebar-collapsed .app {
    grid-template-columns: var(--sidebar-width-collapsed) 1fr;
}

:root.sidebar-collapsed .app__sidebar {
    padding-left: var(--space-2);
    padding-right: var(--space-2);
}

:root.sidebar-collapsed .app__sidebar-title,
:root.sidebar-collapsed .org-box__name,
:root.sidebar-collapsed .nav__label,
:root.sidebar-collapsed .sidebar-footer .nav__item span {
    display: none;
}

:root.sidebar-collapsed .app__sidebar-header {
    justify-content: center;
    padding-left: 0;
    padding-right: 0;
}

:root.sidebar-collapsed .sidebar-toggle .icon {
    transform: rotate(180deg);
}

:root.sidebar-collapsed .org-box {
    justify-content: center;
    margin-left: var(--space-2);
    margin-right: var(--space-2);
    padding: var(--space-2);
}

:root.sidebar-collapsed .nav__item {
    justify-content: center;
    padding: 0;
}

.app__main {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.app__header {
    background: var(--color-header-bg);
    border-bottom: 1px solid var(--color-border);
    height: var(--header-height);
    display: flex;
    align-items: center;
    padding: 0 var(--space-8);
    position: relative;
    top: 0;
    z-index: var(--z-header);
}

.app__content {
    flex: 1;
    padding: var(--space-8);
    max-width: var(--container-max);
    width: 100%;
    /* `max-width` caps this below `.app__main`'s full width on anything wider
       than ~1200px + sidebar; without `margin: auto` a flex child doesn't
       center itself on the cross axis, so the capped box just sat flush
       against the left edge with all the leftover space stranded on the
       right. This only repositions an already-capped box — it can't be what
       introduces horizontal scroll. */
    margin: 0 auto;
}

/* Generic spacing primitives — useful inside any page. */

.stack {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.stack--sm   { gap: var(--space-2); }
.stack--lg   { gap: var(--space-6); }
.stack--xl   { gap: var(--space-8); }

.row {
    display: flex;
    align-items: center;
    gap: var(--space-3);
}

.row--between {
    justify-content: space-between;
}

.grid {
    display: grid;
    gap: var(--space-4);
}

.grid--cards-4 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
}

/* Dashboard KPI strip (5 tiles). */
.grid--cards-5 {
    grid-template-columns: repeat(5, minmax(0, 1fr));
}

/* Wider-first order matters: both blocks match a narrow viewport, and the
   960px block must come last so its 2-column rule wins over the 1200px
   block's 3-column one at small widths. */
@media (max-width: 1200px) {
    .grid--cards-5 {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (max-width: 960px) {
    .app {
        grid-template-columns: 1fr;
    }
    .app__sidebar {
        position: static;
        height: auto;
    }
    .grid--cards-4 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
    .grid--cards-5 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* Standalone auth shell — full-page centered card. Used by /login and /register. */

.auth-layout {
    min-height: 100vh;
    background: var(--color-surface);
    display: grid;
    place-items: center;
    padding: var(--space-8);
}
