/* ============================================================================
   AROS — Layout & Navigation  (Book 011 §10, §7.1, §9)
   ----------------------------------------------------------------------------
   The application SHELL: left rail, header, filter bar, page rhythm, grids.
   Loaded LAST (styles.css -> aros/tokens.css -> aros/components.css -> here),
   so plain selectors override the legacy Apple-Light shell without !important.

   Bindings: semantic tokens only (AROS-011-009). No hex, no raw length outside
   the --space-* scale, except the four breakpoint literals — custom properties
   are invalid inside a media condition, so --bp-sm/md/lg/xl are written out:

       --bp-sm  480px      --bp-lg  1024px
       --bp-md  768px      --bp-xl  1280px

   Requirements realised here:
     -107  token breakpoints + one grid system
     -108  rail -> horizontal scroller, grids stack, tables scroll in-container
     -109  desktop multi-column, compact-but-AA density
     -110  env(safe-area-inset-*) honoured on the fixed chrome
     -111  no horizontal page scroll, ever
     -038  nav is keyboard-operable; active = surface + weight + marker
     -103  >=44px targets on touch
   ==========================================================================*/


/* ============================================================================
   0. SHELL GEOMETRY CONSTANTS
   ==========================================================================*/
:root {
  /* The collapsed rail width and its expanded width. 210px is load-bearing:
     "P&L / Commissions" is the longest label and clipped at 180px. */
  /* One width, always. The rail used to sit at 64px and expand to 210px on
     hover, which meant 17 unlabelled glyphs at rest — unguessable ("Kitchen
     Prep" vs "Forecast" vs "Pitch") and unscannable without interacting. It
     also shifted the content edge on every hover. */
  --shell-rail-w:          208px;

  /* Mobile top-bar height = one 44px touch target plus breathing room. */
  --shell-topbar-h: 56px;

  /* Content measure (AROS-011-107). Tune it at --layout-max-width in tokens.css.
     1440 left 208px of dead gutter each side on a 1920 display and squeezed the
     6-up KPI strip below the width a crore-scale rupee figure needs; 1680 is the
     widest measure that still centres rather than sprawls. */
  --shell-content-max: var(--layout-max-width, 1440px);
}


/* ============================================================================
   1. PAGE FRAME  — AROS-011-107 / -111
   ==========================================================================*/

/* The rail is fixed, so the wrap is inset by exactly its width. Side padding
   grows past the gutter once the viewport can no longer be filled at the
   content measure, which centres the surface on wide displays without a
   wrapper element. max() collapses to the gutter on anything narrower. */
.dashboard-wrap {
  position: relative;
  z-index: 1;
  margin: 0 0 0 var(--shell-rail-w);
  padding-block: var(--space-7) var(--space-9);
  padding-inline: max(
    var(--space-8),
    (100vw - var(--shell-rail-w) - var(--shell-content-max)) / 2
  );
}

.page-content {
  display: none;
  /* A grid/flex child of unknown width must be allowed to shrink or its
     content sets the floor and the body scrolls sideways (AROS-011-111). */
  min-width: 0;
}

.page-content.active {
  display: block;
}


/* ============================================================================
   2. LEFT RAIL  — §4.5, AROS-011-038 / -108 / -110
   ==========================================================================*/
.sidebar {
  position: fixed;
  inset: 0 auto 0 0;
  width: var(--shell-rail-w);
  height: 100vh;
  height: 100dvh;
  z-index: var(--z-nav);

  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);

  padding-block: calc(var(--space-5) + var(--safe-top)) var(--space-4);
  padding-inline: 0;

  background: var(--color-surface);
  backdrop-filter: var(--surface-blur);
  -webkit-backdrop-filter: var(--surface-blur);
  border-right: var(--border-width-hairline) solid var(--color-border);
  box-shadow: var(--elevation-raised);

  overflow: hidden;
  transition: width var(--motion-standard) var(--ease-standard);
}

/* No hover expansion: the rail is already at its full width. The old
   expand-on-hover was also a keyboard trap that needed :focus-within to undo. */

.sidebar-logo {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: var(--space-4);
}

/* 17 destinations do not fit a short laptop viewport. The rail scrolls
   internally rather than clipping the tail of the nav. The scrollbar is
   suppressed because its gutter would eat the label measure the 210px
   expanded width is sized against. */
.sidebar-nav {
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: 0 var(--space-3);
  overflow-x: hidden;
  overflow-y: auto;
  scrollbar-width: none;
  overscroll-behavior: contain;
}

.sidebar-nav::-webkit-scrollbar {
  width: 0;
  height: 0;
}

.nav-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 30px;
  padding: 5px 10px;
  border-radius: var(--radius-sm, 5px);
  color: var(--color-text-muted);
  text-decoration: none;
  font-size: 12.5px;
  font-weight: var(--font-weight-medium, 500);
  white-space: nowrap;
  transition: background var(--motion-fast) var(--ease-standard),
              color var(--motion-fast) var(--ease-standard);
}

.nav-item svg {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
}

/* flex:1/min-width:0 keeps the label inside the 44px collapsed track instead
   of overflowing it — otherwise focusing a rail item scrolls the hidden
   overflow and the icon column visibly jumps. */
.nav-label {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.nav-item:hover {
  background: var(--color-state-hover);
  color: var(--color-text);
}

.nav-item:focus-visible {
  outline: var(--focus-ring-width) solid var(--color-focus-ring);
  outline-offset: -2px;
}

/* Active = token surface + weight + a saffron marker. Three cues, none of
   them colour alone (AROS-011-038 / -100). Saffron is the sanctioned accent
   for active markers (§1.3) and is never load-bearing text. */
.nav-item.active,
.nav-item[aria-current="page"] {
  background: var(--color-state-selected);
  color: var(--color-text);
  font-weight: var(--font-weight-bold);
  box-shadow: inset 0 0 0 1px var(--color-border);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.nav-item.active::before,
.nav-item[aria-current="page"]::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 18px;
  border-radius: 0 var(--space-1) var(--space-1) 0;
  background: var(--color-accent-strong);
}

/* Short viewports: tighten the vertical rhythm before falling back to scroll.
   Scoped above --bp-md so it cannot collide with the mobile top bar. */
@media (min-width: 769px) and (max-height: 760px) {
  .sidebar-logo {
    margin-bottom: var(--space-3);
  }

  .nav-item {
    min-height: 34px;
    padding-block: var(--space-2);
  }
}


/* ============================================================================
   3. HEADER  — §7.1
   ==========================================================================*/
.dashboard-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5) 0 var(--space-6);
  margin-bottom: var(--space-5);
}

.header-left {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-width: 0;
}

.logo-mark {
  flex: 0 0 auto;
}

.logo-mark svg,
.logo-mark img {
  display: block;
}

.header-title {
  color: var(--color-text);
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
  letter-spacing: var(--letter-spacing-tight);
}

.header-subtitle {
  display: block;
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  letter-spacing: var(--letter-spacing-wide);
}

.header-right {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-4);
  min-width: 0;
}

.last-synced {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  font-variant-numeric: var(--font-numeric-tabular);
}

/* Provenance strip for the loaded range — chrome, not a status signal, so it
   wears surface-alt rather than a hue. */
.data-range-badge {
  display: inline-flex;
  align-items: center;
  min-height: var(--control-height-sm);
  padding: 0 var(--space-4);
  border: var(--border-width-hairline) solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface-alt);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  font-variant-numeric: var(--font-numeric-tabular);
  white-space: nowrap;
}

/* Stale is a state, so it takes a fixed status token plus a weight shift —
   the badge already carries a calendar glyph and literal text, so meaning
   never rests on the hue (AROS-011-011 / -100). */
.data-range-badge.stale {
  background: var(--color-status-serious-surface);
  border-color: var(--color-status-serious);
  color: var(--color-status-serious-text);
  font-weight: var(--font-weight-bold);
}

.data-range-badge.loading {
  opacity: 0.6;
}

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

.user-name {
  color: var(--color-text-muted);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
}

.logout-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--control-height-sm);
  height: var(--control-height-sm);
  border: var(--border-width-hairline) solid transparent;
  border-radius: var(--radius-sm);
  background: var(--color-surface-alt);
  color: var(--color-text-muted);
  cursor: pointer;
  transition: background var(--motion-fast) var(--ease-standard),
              color var(--motion-fast) var(--ease-standard);
}

.logout-btn:hover {
  background: var(--color-status-critical-surface);
  color: var(--color-status-critical-text);
}

.logout-btn:focus-visible {
  outline: var(--focus-ring-width) solid var(--color-focus-ring);
  outline-offset: var(--focus-ring-offset);
}

/* The header action. Ink primary in Graphite, system blue in Apple-Light —
   both resolved from the same semantic role. */
.sync-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--control-height-md);
  padding: 0 var(--space-6);
  border: none;
  border-radius: var(--radius-md);
  background: var(--color-action-primary-bg);
  color: var(--color-action-primary-fg);
  font-family: inherit;
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  box-shadow: none;
  cursor: pointer;
  transition: background var(--motion-fast) var(--ease-standard);
}

.sync-btn:hover {
  transform: none;
  background: var(--color-action-primary-hover);
  box-shadow: none;
  filter: none;
}

.sync-btn:active {
  background: var(--color-action-primary-active);
}

.sync-btn:focus-visible {
  outline: var(--focus-ring-width) solid var(--color-focus-ring);
  outline-offset: var(--focus-ring-offset);
}

/* `#full-pipeline-sync-btn` carries an inline `background:linear-gradient(...)`
   in index.html (markup is owned elsewhere). An inline declaration can only be
   beaten by !important — this is the single one in this file. */
#full-pipeline-sync-btn {
  background: var(--color-action-secondary-bg) !important;
  color: var(--color-action-secondary-fg);
  box-shadow: inset 0 0 0 1px var(--color-action-secondary-border);
}


/* ============================================================================
   4. FILTER BAR  — §7.1, AROS-011-082
   ==========================================================================*/
.filter-bar {
  position: relative;
  z-index: var(--z-raised);
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  column-gap: var(--space-4);
  row-gap: var(--space-4);
  padding: var(--space-4) var(--space-6);
  margin-bottom: var(--space-5);
  overflow: visible;
}

.filter-group {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: var(--space-2);
  flex-shrink: 0;
  min-width: 0;
}

.filter-label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--letter-spacing-wide);
  white-space: nowrap;
}

.filter-label svg {
  flex: 0 0 auto;
  opacity: 0.6;
}

.filter-input {
  min-width: 140px;
}

.filter-apply-btn {
  align-self: flex-end;
  white-space: nowrap;
}

/* The echo of the active scope (AROS-011-082). Chrome, not an alert: no hue,
   no gradient. */
.filter-context-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-5);
  margin: 0 0 var(--space-4);
  border: var(--border-width-hairline) solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-alt);
  color: var(--color-text-muted);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  font-variant-numeric: var(--font-numeric-tabular);
  letter-spacing: var(--letter-spacing-normal);
}

.filter-context-bar .ctx-separator {
  color: var(--color-border-strong);
  font-weight: var(--font-weight-regular);
  opacity: 1;
}


/* ============================================================================
   5. PAGE CHROME & RHYTHM  — §7.1
   ==========================================================================*/
.comm-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}

.comm-header-left {
  min-width: 0;
}

.comm-page-title {
  color: var(--color-text);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
  letter-spacing: var(--letter-spacing-tight);
}

.comm-page-subtitle {
  display: block;
  margin-top: var(--space-1);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-normal);
}


/* ============================================================================
   6. GRIDS  — AROS-011-107 / -108 / -109
   ----------------------------------------------------------------------------
   minmax(0, 1fr) on every track: `1fr` alone floors at min-content, which is
   how a wide KPI value or a nowrap table pushes the body sideways.
   ==========================================================================*/
/* Six across only once a track is wide enough to hold a crore-scale rupee
   figure at hero size (~250px). Below that the numbers clip, so the strip
   folds to two rows of three rather than shrinking the number. */
.summary-cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}

@media (min-width: 1760px) {
  .summary-cards {
    grid-template-columns: repeat(6, minmax(0, 1fr));
  }
}

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

.summary-cards-extra {
  margin-bottom: var(--space-5);
}

.extra-kpi-cards {
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--space-4);
}

.charts-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}

.charts-grid-3col {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.chart-full-width {
  grid-column: 1 / -1;
}

.chart-full-width .chart-body {
  min-height: 220px;
}

/* Every direct grid child, whatever it is. */
.summary-cards > *,
.extra-kpi-cards > *,
.charts-grid > * {
  min-width: 0;
}

/* A Panel clips its own content; wide children (tables, pill rows) carry
   their own scroller (AROS-011-035). */
.chart-container {
  min-width: 0;
  overflow: hidden;
}

/* Page-level stacking. Only .charts-grid and .summary-cards carry their own
   margin-bottom, so a page that drops a panel straight into the section — OOS,
   Locations, Forecast — had its panels flush against each other with no gap at
   all. Adjacent block margins collapse, so this never adds to the blocks that
   already space themselves; it only fills the gaps that were zero. */
.page-content > *:not(style) + *:not(style) {
  margin-top: var(--space-6);
}

/* Fixed overlays are not in the stack — an inset:0 box absorbs a top margin as
   a 20px vertical offset and stops centring. */
.page-content > #settlement-modal {
  margin-top: 0;
}


/* ============================================================================
   7. BREAKPOINT: <= --bp-xl (1280px)
   ==========================================================================*/
@media (max-width: 1280px) {
  .dashboard-wrap {
    padding-inline: var(--space-7);
  }
}


/* ============================================================================
   8. BREAKPOINT: <= --bp-lg (1024px)  — tablet, rail still present
   ==========================================================================*/
@media (max-width: 1024px) {
  .summary-cards,
  .summary-cards.financial-cards {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

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

  .charts-grid-3col {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}


/* ============================================================================
   9. BREAKPOINT: <= --bp-md (768px)  — rail becomes a top scroller
   ----------------------------------------------------------------------------
   AROS-011-108 / -103 / -110 / -111
   ==========================================================================*/
@media (max-width: 768px) {
  /* Root-level guard. Wide content already scrolls inside its own container
     (.rep-table-wrap, .pnl-table-wrap, .oos-table-wrap, .rep-mode); this stops
     anything that slips through from scrolling the body. `clip` rather than
     `hidden` so it does not become a scroll container and silently break the
     sticky Reports header/footer. */
  body {
    overflow-x: clip;
  }

  /* 9.1 Rail -> horizontal scroller */
  .sidebar {
    inset: 0 0 auto 0;
    width: 100%;
    height: auto;
    min-height: calc(var(--shell-topbar-h) + var(--safe-top));
    flex-direction: row;
    align-items: center;
    gap: 0;
    padding-block: calc(var(--space-2) + var(--safe-top)) var(--space-2);
    padding-inline: max(var(--space-3), var(--safe-left))
                    max(var(--space-3), var(--safe-right));
    border-right: none;
    border-bottom: var(--border-width-hairline) solid var(--color-border);
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }

  .sidebar::-webkit-scrollbar {
    height: 0;
  }

  .sidebar-logo {
    width: 28px;
    height: 28px;
    margin: 0 var(--space-3) 0 0;
  }

  .sidebar-nav {
    flex: 0 0 auto;
    width: auto;
    flex-direction: row;
    gap: var(--space-1);
    padding: 0;
    overflow: visible;
  }

  .nav-item {
    flex: 0 0 auto;
    gap: var(--space-2);
    min-height: var(--touch-target-min);
    padding: var(--space-2) var(--space-4);
  }

  /* Labels are always visible in the top bar — the rail's hover contract
     does not exist on touch. */
  .nav-label,
  .sidebar:hover .nav-label,
  .sidebar:focus-within .nav-label {
    flex: 0 0 auto;
    opacity: 1;
    font-size: var(--font-size-sm);
  }

  /* The active marker becomes an underline in the horizontal axis. */
  .nav-item.active::before,
  .nav-item[aria-current="page"]::before {
    top: auto;
    bottom: 2px;
    left: var(--space-4);
    right: var(--space-4);
    width: auto;
    height: 2px;
    border-radius: var(--radius-pill);
    transform: none;
  }

  /* 9.2 Content clears the fixed top bar */
  .dashboard-wrap {
    margin-left: 0;
    margin-top: calc(var(--shell-topbar-h) + var(--safe-top));
    padding-inline: max(var(--space-4), var(--safe-left))
                    max(var(--space-4), var(--safe-right));
    padding-block: var(--space-4) calc(var(--space-8) + var(--safe-bottom));
  }

  /* 9.3 Header stacks */
  .dashboard-header {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--space-3);
    padding: var(--space-4) 0;
    margin-bottom: var(--space-4);
  }

  .header-left {
    justify-content: center;
  }

  .header-title {
    font-size: var(--font-size-xl);
  }

  .header-right {
    justify-content: center;
    gap: var(--space-3);
  }

  .user-menu {
    order: -1;
  }

  .logout-btn {
    width: var(--touch-target-min);
    height: var(--touch-target-min);
  }

  .sync-btn {
    min-height: var(--touch-target-min);
    padding-inline: var(--space-5);
  }

  /* 9.4 Filter bar stacks; every control is a full-width touch target */
  .filter-bar {
    flex-direction: column;
    align-items: stretch;
    padding: var(--space-4);
    gap: var(--space-3);
  }

  .filter-group {
    width: 100%;
  }

  .filter-input {
    min-width: 0;
  }

  .period-pills,
  .filter-apply-btn {
    align-self: stretch;
    width: 100%;
    justify-content: center;
  }

  /* Pills wrap rather than pushing the row wider than the viewport. */
  .period-pills {
    flex-wrap: wrap;
  }

  .filter-context-bar {
    padding: var(--space-3) var(--space-4);
    font-size: var(--font-size-sm);
  }

  /* 9.5 Grids stack */
  .summary-cards,
  .summary-cards.financial-cards,
  .extra-kpi-cards {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-3);
    margin-bottom: var(--space-4);
  }

  .charts-grid,
  .charts-grid-3col {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-3);
  }

  .chart-full-width {
    grid-column: 1 / -1;
  }

  /* 9.6 Page headers stack */
  .comm-header {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-3);
  }
}


/* ============================================================================
   10. BREAKPOINT: <= --bp-sm (480px)  — single column
   ==========================================================================*/
@media (max-width: 480px) {
  .summary-cards,
  .summary-cards.financial-cards,
  .extra-kpi-cards {
    grid-template-columns: minmax(0, 1fr);
  }

  .dashboard-wrap {
    padding-inline: max(var(--space-3), var(--safe-left))
                    max(var(--space-3), var(--safe-right));
  }

  .header-title {
    font-size: var(--font-size-lg);
  }

  .header-subtitle {
    font-size: var(--font-size-xs);
  }

  .nav-item {
    padding-inline: var(--space-3);
  }

  .nav-label {
    font-size: var(--font-size-xs);
  }
}


/* ============================================================================
   11. DESKTOP DENSITY OPT-IN  — AROS-011-109
   ----------------------------------------------------------------------------
   Compact rail rhythm only where the pointer is fine; the 44px floor still
   governs every touch context.
   ==========================================================================*/
@media (min-width: 1025px) and (pointer: fine) {
  .nav-item {
    min-height: 38px;
  }
}


/* ============================================================================
   12. REDUCED MOTION  — AROS-011-017 / -104
   ==========================================================================*/
@media (prefers-reduced-motion: reduce) {
  .sidebar,
  .nav-item,
  .nav-label,
  .sync-btn,
  .logout-btn {
    transition: none;
  }
}


/* ============================================================================
   13. PRINT  — the shell is screen-only
   ----------------------------------------------------------------------------
   styles.css already hides the rail/header/filters and zeroes the wrap with
   !important. Only the geometry this file introduces needs neutralising, so
   nothing here leaks into the Reports PDF.
   ==========================================================================*/
@media print {
  .dashboard-wrap {
    margin-left: 0;
    margin-top: 0;
    padding-inline: 0;
    padding-block: 0;
  }

  /* The only page header that survives print is the Reports one; its actions
     are already hidden, so it just needs a tighter rule above the table. */
  .comm-header {
    margin-bottom: var(--space-3);
  }
}


/* ── Grouped rail ─────────────────────────────────────────────────────────────
   Seventeen destinations in one flat list meant rescanning the whole estate to
   find anything, and the tail (Reports, Admin) fell below the fold on a 768px
   viewport with nothing to say it was there. Six labelled groups, sized so the
   whole thing fits without the internal scroller. */
.nav-group {
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.nav-group + .nav-group { margin-top: 11px; }

/* Rule 1: mono uppercase for every label. The group header is chrome, so it is
   the subtle step — it must not compete with the destinations under it. */
.nav-group-label {
  padding: 0 10px 4px;
  font-family: var(--aros-sig-mono, var(--font-mono));
  font-size: 9px;
  font-weight: 600;
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--color-text-subtle);
}

/* The grouped rail above is unconditional and loads after the mobile block at
   line 633, so the flatten has to live here to win. On mobile .sidebar becomes
   a row-direction scroller, but each .nav-group is still a vertical column, so
   the bar took the height of a whole group stack (~217px) instead of one item
   and sat on top of the content. `display: contents` drops the group box and
   promotes its .nav-item children into the row itself. Labels are dropped
   rather than kept as inline separators: they would add six more scroll stops
   to a bar that already scrolls 670px, and the destinations read fine alone. */
@media (max-width: 768px) {
  .nav-group {
    display: contents;
  }

  .nav-group + .nav-group {
    margin-top: 0;
  }

  .nav-group-label {
    display: none;
  }

  /* Hairline where a group used to start, so the six clusters stay legible. */
  .nav-group + .nav-group > .nav-item:first-of-type {
    margin-left: var(--space-2);
    border-left: var(--border-width-hairline) solid var(--color-border);
    padding-left: calc(var(--space-4) + var(--space-2));
  }
}

/* ── Filter bar: Apply must not strand itself ────────────────────────────────
   .filter-bar is a wrapping flex row and the Apply button is its LAST child, so
   the moment the row overflows Apply drops onto a line of its own. Measured at
   1680px: Apply sat 56px below the pills, ending at x=356 in a 1328px bar —
   roughly 970px of empty band. At 2560px it was inline, which is why it looked
   fine on a big monitor and broken on a laptop.

   The fix is to let the PILLS wrap inside their own group instead of forcing the
   whole bar to wrap, and to pin Apply to the end of the row it is on. */
.filter-bar #filter-group-quick,
.filter-bar .filter-group:has(.period-pills) { flex: 1 1 300px; min-width: 0; }
.filter-bar .period-pills { flex-wrap: wrap; }
.filter-bar .filter-apply-btn {
  margin-left: auto;
  align-self: flex-end;
  flex-shrink: 0;
}

/* ── Sign out: a labelled control, not a mystery square ──────────────────────
   It was a 32x32 filled grey box holding a 16px icon and nothing else. The icon
   passed contrast at 5.35:1 — the problem was never legibility, it was that an
   unlabelled filled square in the far corner reads as an empty chip. Give it its
   word and drop the box; the hover state can carry the emphasis instead. */
.logout-btn {
  width: auto;
  height: var(--control-height-sm);
  gap: var(--space-2);
  padding: 0 var(--space-3);
  background: transparent;
  border-color: var(--color-border);
  border-radius: var(--radius-pill, 999px);
}
.logout-label {
  font-size: var(--font-size-xs, 12px);
  font-weight: 500;
  letter-spacing: .02em;
  white-space: nowrap;
}
@media (max-width: 560px) {
  /* Narrow: the icon alone is acceptable once it is the only thing in the row. */
  .logout-label { display: none; }
  .logout-btn { width: var(--control-height-sm); padding: 0; }
}
